2014-12-12 6 views
8

Unter Berücksichtigung der Struktur VIPERiOS VIPER-Architektur, wer muss ein ganzes Modul instanziieren?

enter image description here

Ich habe zwei Modulen A und B. Das erste Modul A, über Moderator, will eine Aktion durchzuführen, die in dem Modul B durchgeführt werden muss, so sagt seinem Drahtgitter, es zu tun. Die Frage ist, wer für die Instanziierung des gesamten Moduls verantwortlich ist (View, Interactor, Presenter ...). Ich sah einige Beispiele mit verschiedenen Ansätzen:

  • Erstellen Sie alle Module am Anfang der App.
  • Erstellen Sie das gesamte Modul im Drahtmodell des Moduls. In diesem Fall instanziiert eine Klassenmethode von BWireframe das gesamte B-Modul.

zu berücksichtigen, dass das Drahtgitter für das Routing zuständig ist, ist es auch verantwortlich sein Modul zu schaffen?

+0

Generell bevorzuge ich Wireframe, um sein Modul zu erstellen, Wenn wir alle Module beim Starten erstellen, dann wenn es viele Module gibt, dann macht es keinen Sinn, also stimme ich zu, dass der zweite Ansatz besser ist. – Abhishek

Antwort

15

TL; DR: Ich würde Ihnen empfehlen, einen DI Framework wie Typhoon verwenden sollten, und dass Griff Instanziierung lassen.

Der Grund, warum Sie wahrscheinlich nicht möchten, dass Ihre Wireframes alles in einem VIPER-Modul (View, Presenter, Interactor, DataManager) instanziieren, ist, dass Sie Abhängigkeiten direkt zu jeder dieser Komponenten erstellen.

Abhängigkeiten machen Software beständig zu ändern: auf, wenn wir es mit unseren onion architecture/hexagonal architecture Hüten denken, die Grenzen von mindestens zwei getrennten Schichten der Zwiebel würden überqueren die Drahtgitter von etwa nicht nur die Aussicht zu wissen, aber die Daten Manager.

Dies zwingt uns, Wireframes als generische Infrastrukturklasse zu behandeln: d. H. Etwas auf der äußersten Ebene Ihrer Anwendung.

Dies widerspricht jedoch die andere (und die mehr echte) Verantwortung des Drahtmodells: Navigation zu tun. Während dies immer noch die Infrastrukturschicht ist, gehört sie fest und spezifisch in UIKit (-presentViewController: etc.).

Also IMHO, VIPER Drahtmodell macht zu viel.

Das einzig Vernünftige ist, die beiden Aufgaben aufgeteilt:

  1. Initialisierung von VIPER Klassen: Sie factory vorstellen können, oder DI-Tools verwenden, die dieses Problem entwickelt werden
  2. tun Navigation zu lösen: das bleibt in der Zuständigkeit eines Wireframe.

Zusätzliche Hinweise

Wenn Sie sich fragen, „die das nächste Modul instanziiert?“, Dann wieder, IMHO, ich denke, es ist nicht richtig, dass einige Module A ‚s Drahtmodell spricht mit Module B‘ s Drahtgitter trotz was die VIPER post sagt.

Der Grund dafür ist, dass Module A würde jetzt auf Module B abhängig gemacht werden, was eine enge Kopplung verursacht: dies den Zweck der Module. Viel mehr Diskussion über dieses Thema bei VIPER-TODO project at GitHub =]

Hoffe das hilft.

+0

Danke Fatuhoku, das war sehr aufschlussreich. In meinem Projekt habe ich vier Module und ich hatte einige Bedenken. Mein nächster Schritt wird Typhoon sein, in der nächsten Version :) Danke nochmal. – emenegro

+0

Ich habe von diesem Post zum ersten Mal von Typhoon erfahren .... mein Leben ist jetzt 1000x besser. Ich schulde dir ein beer @ fatuhoku – SleepsOnNewspapers

+0

@ SleepsOnNewspapers Haha. Ich bin froh, dass ich Ihnen helfen kann =] – fatuhoku

1

Ich denke, dass das Eingangstor zu einem Modul das Drahtgitter ist, also stimme ich Ihrem zweiten Ansatz zu.

Erstellen eines Moduls umfasst die Erstellung aller seiner Objekte und es scheint mir eine Art verschwenderisch.

1

die eine Reihe von Codewiederholungs beseitigen wird auf seinem eigenen Router Modulinitialisierung Code, speziell für große Projekte. Sie müssen diese Erweiterungen erstellen, sobald:

// ReusableView.swift 
 
protocol ReusableView: class {} 
 

 
extension ReusableView { 
 
    static var reuseIdentifier: String { 
 
     return String(describing: self) 
 
    } 
 
} 
 

 

 
// UIViewController.swift 
 
extension UIViewController: ReusableView { } 
 

 

 
// UIStoryboard.swift 
 
extension UIStoryboard { 
 
    func instantiateViewController() -> T where T: ReusableView { 
 
     return instantiateViewController(withIdentifier: T.reuseIdentifier) as! T 
 
    } 
 
}

Und dann Initialisierungscode auf dem Router jedes VIPER Modul verlassen:

// MainSearchRouter.swift 
 
class MainSearchRouter { 
 

 
    // MARK: Properties 
 
    weak var view: UIViewController? 
 

 
    // MARK: Static methods 
 
    static func setupModule() -> MainSearchViewController { 
 
     let viewController = UIStoryboard(name: MainSearchViewController.storyboardName, bundle: nil).instantiateViewController() as MainSearchViewController 
 
     let presenter = MainSearchPresenter() 
 
     let router = MainSearchRouter() 
 
     let interactor = MainSearchInteractor() 
 

 
     viewController.presenter = presenter 
 

 
     presenter.view = viewController 
 
     presenter.router = router 
 
     presenter.interactor = interactor 
 

 
     router.view = viewController 
 

 
     interactor.output = presenter 
 

 
     return viewController 
 
    } 
 
}

Es könnte wie eine Menge Schritte scheinen, aber eine gute Nachricht: t Das oben erwähnte Plugin automatisiert das auch!

+0

Danke Marcelo, ich schaue mir das an, klingt interessant! Schließlich löste ich dies auf die gleiche Weise, ich benutze ein Protokoll namens 'ModuleFactory', um das gesamte Modul zu instanziieren. Sie können hier ein Beispiel sehen: https: // github.com/emenegro/raumzellen-ios – emenegro