Должен ли ViewController-Presenter-Interactor иметь отношение один к одному

Я читаю о VIPER и понимаю, что обычно viewController связан с одним ведущим, а один ведущий разговаривает с одним Interactor.

Но что, если у нас есть страницы основных сведений или страницы сведений о списках. Чтобы отобразить список элементов, у меня был бы один контроллер/ведущий для отображения списка и другой контроллер/ведущий для отображения деталей. А FetchList и FetchDetail должны принадлежать одному и тому же интерактору.

Если эти два презентатора взаимодействуют с этим интерактором, им придется реализовать оба метода FetchList и FetchDetail. И одна из этих двух реализаций метода будет пустой.


person Pragmatic    schedule 27.11.2016    source источник


Ответы (2)


У вас должно быть два отдельных модуля VIPER: MainItems и DetailedItems.

Прочтите этот пост (https://www.ckl.io/blog/best-practices-viper-architecture) и узнайте, как использовать делегатов для отправки данных между модулями VIPER. Обратите внимание, что FetchList и FetchDetail должны принадлежать разным интеракторам:

// 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
        ...
        }
}

person Marcelo Gracietti    schedule 11.04.2017

Насколько я понимаю, у вас есть один вид/контроллер представления и презентер на каждый экран, а затем один интерактор на вариант использования, что, вероятно, означает более одного на экран. Это хорошая практика с точки зрения принципа единой ответственности и, следовательно, помогает тестированию. Но иногда делается уступка, и интерактор обрабатывает несколько вариантов использования.

person Andrew Ebling    schedule 24.02.2017