ViewController-Presenter-Interactor应该具有一对一的关系

时间:2016-11-27 14:41:45

标签: ios mvp viper-architecture

我正在阅读有关VIPER的内容,我的理解是 - 通常一个viewController与一个演示者有关,一个演示者与一个Interactor进行对话。

但是,如果我们有master-details页面或list-detail页面怎么办?要显示项目列表,我将有一个控制器/ Presenter显示列表,另一个控制器/演示者显示详细信息。并且FetchList和FetchDetail应属于同一个交互器。

如果这两个演示者与此交互器进行通信,则必须同时实现FetchList和FetchDetail方法。这两种方法的实现之一是空的。

2 个答案:

答案 0 :(得分:1)

您应该有两个独立的VIPER模块:MainItems和DetailedItems。

阅读这篇文章(https://www.ckl.io/blog/best-practices-viper-architecture),了解如何使用委托在VIPER模块之间发送数据。请注意,FetchListFetchDetail应属于不同的交互者:

// 1. Declare which messages can be sent to the delegate

// ProductScreenDelegate.swift
protocol ProductScreenDelegate {
//Add arguments if you need to send some information
    func onProductScreenDismissed()
    func onProductSelected(_ product: Product?)
}

// 2. Call the delegate when you need to send him a message

// ProductPresenter.swift
class ProductPresenter {

    // MARK: Properties
    weak var view: ProductView?
    var router: ProductWireframe?
    var interactor: ProductUseCase?
    var delegate: ProductScreenDelegate?
}

extension ProductPresenter: ProductPresentation {

    //View tells Presenter that view disappeared
    func onViewDidDisappear() {

        //Presenter tells its delegate that the screen was dismissed
        delegate?.onProductScreenDismissed()
    }
}

// 3. Implement the delegate protocol to do something when you receive the message

// ScannerPresenter.swift
class ScannerPresenter: ProductScreenDelegate {

    //Presenter receives the message from the sender
    func onProductScreenDismissed() {

        //Presenter tells view what to do once product screen was dismissed
        view?.startScanning()
    }
    ...
}

// 4. Link the delegate from the Product presenter in order to proper initialize it

// File ScannerRouter.swift
class ProductRouter {

    static func setupModule(delegate: ProductScreenDelegate?) -> ProductViewController {
        ...
        let presenter = ScannerPresenter()

        presenter.view = view
        presenter.interactor = interactor
        presenter.router = router
        presenter.delegate = delegate // Add this line to link the delegate
        ...
        }
}

答案 1 :(得分:0)

我的理解是每个屏幕有一个视图/视图控制器和演示者,然后每个用例有一个交互器 ,这可能意味着每个屏幕不止一个。从单一责任原则的角度来看,这是一种很好的做法,因此有助于测试。但有时会做出让步,并且交互者会处理多个用例。