2015-03-06 8 views
9

Ich versuche, die von Robert Martin beschriebenen Clean Architecture zu implementieren. Genauer gesagt verwende ich VIPER, die eine iOS-Version von Clean Architecture ist.Saubere Architektur - Robert Martin - So verbinden Sie Anwendungsfälle

Das Problem, das ich habe, ist wie folgt:

Der Benutzer startet mit Plätzen (Pins) auf sie auf einer Karte an. Wenn er auf eine Schaltfläche klickt, wird eine PIN gelöscht und er wird zu einer anderen Ansicht geleitet, um den Ort zu erstellen (oder zu bearbeiten, wenn es sich um einen Klick auf eine vorhandene PIN handelt) (oder abzubrechen). In dieser anderen Ansicht kann der Benutzer die Ortsinformationen bearbeiten und dann auf "Zurück" oder "Fertig" (oder "Bearbeiten") klicken. Wenn er auf "Fertig" klickt, sendet der PlaceDetailsViewController eine Nachricht an den PlaceDetailsPresenter mit den Ortsinformationen und der PlaceDetailsPresenter verwendet den CreatePlaceInteractor, um den Ort zu erstellen. Dieser Interaktor gibt die GUID zurück, die zur Identifizierung des Ortes verwendet wird.

Wenn der Benutzer zurückklickt, bevor er den Ort erstellt, kehrt er zur Karte zurück und der abgelegte Pin geht hoch und weg (da es keine GUID hat, ist es ein neuer Ort und verschwindet). Wenn er nach dem Erstellen zurückklickt, bleibt der Pin dort (weil er eine GUID haben sollte).

Wie sollte ich all das verbinden und wo sollten die Ortsinformationen (einschließlich GUID) gespeichert werden? Um ein wenig mehr zu klären:

  1. Wer die MapPresenter informieren sollte, dass der Stift dort bleibt oder geht weg? Ist es der PlaceDetailsPresenter oder soll ich diese Informationen an die PlaceDetailsWireframe -> MapWireframe -> MapPresenter -> MapView übergeben?
  2. Bevor Sie zurückgehen, wo sollte diese GUID gespeichert werden, in der PlaceDetailsPresenter oder in der PlaceDetailsViewController?

Gerade jetzt, dass das, was ich habe: enter image description here

EDIT:

Grundsätzlich denke ich, das Problem, dass VIPER von Robert Martin Clean Architektur kam und er kommt von einem Web (Rails) Hintergrund, also denkt er nicht viel über den Staat nach (oder präzisiert ihn nicht in seinen Gesprächen).

Das ist hauptsächlich meine Frage, wo sollte der Zustand gespeichert werden, wie sollten die verschiedenen Module kommunizieren, sollte es über den Wireframe, oder über die Datenbank, oder über die Interaktoren oder über die Presenter untereinander kommunizieren hier https://github.com/objcio/issue-13-viper-swift.

+0

Ich bin nur mit VIPER anfangen, aber es fühlt sich für mich falsch Moderatoren voneinander wissen zu haben. Ich bevorzuge Module, die über den Drahtmodell/Router miteinander kommunizieren. Ich bin glücklich, hier korrigiert zu werden, da ich immer noch diese Architektur lerne. – bennythemink

+0

Ich tendiere dazu, genauso zu denken wie du, obwohl ich immer noch keine entscheidende Antwort gefunden habe, wie man Informationen zwischen ihnen weitergibt, ob es besser ist, Datenstrukturen durch Drahtgitter zu übertragen (2 Optionen hier, benutze immer die gleiche, große, Datenstruktur, oder ändern Sie sich auf dem Weg, um nur die minimale Menge an notwendigen Informationen zu übergeben (was zur Folge mehr nicht wiederverwendbare Klassen zu schaffen), oder speichern Sie den Zustand in Interacter und verwenden Sie sie, um die Informationen in der anderen Presenter zu erhalten. Ich habe eine weitere Stackoverflow-Frage gestellt, die erklärt, was ich unter Big Data-Struktur verstehe, die ich bisher noch nicht gefunden habe. –

+0

http://stackoverflow.com/questions/29054526/viper-should-the-interactor-return-only-the-necessary-information –

Antwort

15

Ich weiß nicht viel über Viper, also kann ich dazu nichts sagen. Der Bruttozustand des Systems sollte jedoch in den Entitätsobjekten enthalten sein und von den Interaktoren manipuliert werden. Der detaillierte Status der GUI (Auswahlrechtecke usw.) sollte durch eine spezielle Verbindung zwischen dem Controller und dem Presenter verwaltet werden.

In Ihrem Fall gibt es zwei Bildschirme. Die Karte und der Platzeditor. Wenn Sie auf die Karte klicken, wird entweder der placePinController aufgerufen. Er sammelt den Speicherort des Klicks und alle anderen kontextabhängigen Daten, konstruiert eine placePinRequest-Datenstruktur und übergibt sie an den PlacePinInteractor, der den Speicherort des Pins überprüft, bei Bedarf validiert, eine Place-Entität zum Aufzeichnen des Pins erstellt und eine EditPlaceReponse erstellt Objekt und übergibt es an den EditPlacePresenter, der den Platzeditor-Bildschirm öffnet.

Wenn die Schaltfläche Fertig auf dem Editor des Bereichseditors geklickt wird, wird der EditPlaceController aufgerufen, der die bearbeiteten Daten in eine EditPlaceRequest-Datenstruktur aufnimmt und an den EditPlaceInteractor übergibt. etc ..

Sie ausdrücklich darum gebeten, über die GUID des Stiftes. Das würde von der Entität Place erstellt und an den PlacePinInteractor editPlacePresenter zurückgegeben.

+0

Vielleicht war ich nicht ganz klar, aber was ment ich war: der Klick in das geschieht MapPresenter, aber der Ort wird erst später erstellt, wenn die Verwendung "done" in der PlaceDetailsViewController drückt (was der Ansicht entspricht). Wenn der Benutzer auf "Fertig" klickt, wird der Ort erstellt. Wenn der Benutzer auf "Zurück" klickt, sollte er zum MapPresenter zurückkehren und die PIN dann nicht verwerfen (oder sie abweisen, wenn sie nicht erstellt wurde). –

+0

Mit Status meine ich Dinge wie die Pin, die vorübergehend in der Map erstellt wurde. Wenn wir also vom PlaceDetailsViewController/Presenter zurückkommen, wissen wir, welche Pin gelöscht oder beibehalten werden muss (und geben Sie die GUID an, mit der sie verknüpft werden soll). –

+0

Denken Sie an "fertig" und "zurück" als verschiedene Anwendungsfälle (verschiedene Interaktoren). –

0

Im reinen VIPER Router sollte die Moduleingabe in Form eines Protokolls erfolgen. Und Module Presenter sollte sich daran halten. Wenn der Router also andere Modul-Router verwendet, um ein neues Modul zu montieren, übergibt er seine Eingabe an ihn.

der zweite Router ordnet dann den Eingang zu seinem Ausgang Vorführer. Im Grunde wird Presenter des ersten Moduls zum Delegierten für die zweiten Module Presenter.

Wenn also ein Benutzer einen Ort auswählt, fragt MapPresenter MapInteractor nach einer GUID und weist MapRouter an, zu Details für diese GUID zu navigieren.

MapRouter fragt PlaceDetailsRouter PlaceDetailsModule für diese GUID zu montieren und übergibt MapModuleInput zu. PlaceDetailsRouter weist MapModuleInput PlaceDetailsPresenter zu. PlaceDetailsRouter setzt GUID in der PlaceDetailsInteractor

Verwandte Themen