RxMVVM 使用输入/输出和复杂映射的问题

RxMVVM using Inputs / Outputs and issues with complex mapping

鉴于 this post, here is an example view model:

描述的设计模式
final class SayHelloViewModel: ViewModelType {
    let input: Input
    let output: Output

    struct Input {
        let name: AnyObserver<String>
        let validate: AnyObserver<Void>
    }

    struct Output {
        let greeting: Driver<String>
    }

    private let nameSubject = ReplaySubject<String>.create(bufferSize: 1)
    private let validateSubject = PublishSubject<Void>()

    init() {
        let greeting = validateSubject
            .withLatestFrom(nameSubject)
            .map { name in
                return "Hello \(name)!"
            }
            .asDriver(onErrorJustReturn: ":-(")

        self.output = Output(greeting: greeting)
        self.input = Input(name: nameSubject.asObserver(), validate: validateSubject.asObserver())
    }
}

以上似乎是一个非常好的设计模式。我唯一的问题是,当 nameSubject -> greeting 中的映射函数比此处显示的更复杂并且需要抽象为它自己的函数时会发生什么?

在下面的场景中,我将映射功能抽象到它自己的函数中,称为 sayHello. 当然,现在的问题是我们在初始化 self 之前引用了 self。如何在重要示例中维护此设计模式?

final class SayHelloViewModel {
    let input: Input
    let output: Output

    struct Input {
        let name: AnyObserver<String>
        let validate: AnyObserver<Void>
    }

    struct Output {
        let greeting: Driver<String>
    }

    private let nameSubject = ReplaySubject<String>.create(bufferSize: 1)
    private let validateSubject = PublishSubject<Void>()

    init() {
        let greeting = validateSubject
            .withLatestFrom(nameSubject)
            .map(sayHello)
            .asDriver(onErrorJustReturn: ":-(")
        self.output = Output(greeting: greeting)
        self.input = Input(name: nameSubject.asObserver(), validate: validateSubject.asObserver())
    }

    private func sayHello(name: String) -> String {
        return "Hello \(name)!"
    }
}

只需将您的映射函数设为私有免费函数,而不是 class 成员。如果它需要访问成员,它只需要自己成为成员,这在这种模式下是极不可能的。

编辑:您也可以通过避开主题并像这样直接对 inputs/outputs 进行操作来清理它:

final struct SayHelloViewModel {

    struct Input {
        let name: Observable<String>
        let validate: Observable<Void>
    }

    // An output
    let greeting: Driver<String>

    init(inputs: Input) {
        let greeting = input.validate
            .withLatestFrom(input.name)
            .map(sayHello)
            .asDriver(onErrorJustReturn: ":-(")
    }
}

private func sayHello(name: String) -> String {
    return "Hello \(name)!"
}

您可以更进一步,根本不使用 struct/class 并使其成为 returns 一个 tuple/struct 输出的纯粹函数。