2015-03-06 30 views
9

Sto cercando di implementare il Clean Architecture descritto da Robert Martin. In particolare sto usando VIPER che è una versione iOS di Clean Architecture.Architettura pulita - Robert Martin - Come collegare casi d'uso

Il problema che ho è la seguente:

L'utente inizia guardando una mappa con i luoghi (pin) su di esso. Se fa clic su un pulsante, viene rimosso un pin e viene portato a un'altra vista per creare (o modificare se si tratta di un clic su un pin esistente) il luogo (o annullare). In questa altra vista, l'utente può modificare le informazioni del luogo e quindi fare clic su "Indietro" o "Fatto" (o "Modifica"). Se fa clic su "done", PlaceDetailsViewController invia un messaggio a PlaceDetailsPresenter con le informazioni sul luogo e PlaceDetailsPresenter utilizza CreatePlaceInteractor per creare il luogo. Questo interactor restituisce il GUID che viene utilizzato per identificare il luogo.

Se l'utente fa clic indietro prima di creare il luogo, torna alla mappa e il pin rilasciato va su e giù (poiché non ha GUID, è un nuovo posto e va via). Se fa clic indietro dopo la creazione, il pin rimane lì (perché dovrebbe avere un GUID).

Come devo collegare tutto questo e dove devono essere memorizzate le informazioni sul luogo (incluso GUID)? Per chiarire un po 'di più:

  1. Chi dovrebbe informare il MapPresenter che il perno rimane lì o se ne va? È PlaceDetailsPresenter o devo passare queste informazioni a PlaceDetailsWireframe -> MapWireframe -> MapPresenter -> MapView?
  2. Prima di tornare indietro, dove dovrebbe essere memorizzato questo GUID, in PlaceDetailsPresenter o in PlaceDetailsViewController?

Proprio ora che è quello che ho: enter image description here

EDIT:

Fondamentalmente penso che il problema è che VIPER è venuto da Robert Martin Clean Architettura e proviene da una Web (Rails) di fondo, quindi non pensa molto allo stato (o non lo specifica nei suoi discorsi).

Quale è principalmente la mia domanda, dove dovrebbe essere memorizzato lo stato, come dovrebbero comunicare i diversi moduli, se attraverso il Wireframe, o attraverso il database, o attraverso gli Interpreti, o attraverso i Presentatori che comunicano tra loro come qui https://github.com/objcio/issue-13-viper-swift.

+0

Sono appena all'inizio con VIPER ma mi sembra sbagliato avere i presentatori che conoscono l'un l'altro. Sono favorevole ai moduli che comunicano tra loro tramite Wireframe/Router. Sono felice di essere corretto qui mentre sto ancora imparando questa architettura. – bennythemink

+0

Tendo a pensare nello stesso modo in cui lo fai tu, anche se non ho ancora trovato una risposta decisiva su come passare le informazioni tra loro, se è meglio passare le strutture dati attraverso i wireframe (2 opzioni qui, usa sempre la stessa, grande, struttura dei dati, o continuare a cambiare lungo il percorso per passare solo la quantità minima di informazioni necessarie (che finisce per creare più classi non riutilizzabili)), o salvare lo stato in Interactor e usarle per recuperare le informazioni nell'altro presentatore. Ho pubblicato un'altra domanda StackOverflow che spiega cosa intendo per struttura dei big data, ma non ho potuto ancora trovarla. –

+0

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

risposta

15

Non so molto di Viper, quindi non posso commentare a riguardo. Tuttavia, lo stato grossolano del sistema dovrebbe essere contenuto negli oggetti entità e manipolato dagli interattori. Lo stato dettagliato della GUI (rettangoli di selezione, ecc.) Dovrebbe essere gestito da una connessione speciale tra il controller e il relatore.

Nel tuo caso ci sono due schermi. La mappa e l'editor di luoghi. Facendo clic sulla mappa, viene richiamato placePinController. Raccoglie la posizione del clic e qualsiasi altro dato contestuale, costruisce una struttura di dati placePinRequest e passa a PlacePinInteractor che controlla la posizione del pin, lo convalida se necessario, crea un'entità Place per registrare il pin, costruisce un EditPlaceReponse oggetto e passa a EditPlacePresenter che visualizza la schermata dell'editor dei luoghi.

Se si fa clic sul pulsante Fine sulla schermata dell'editor di posto, viene richiamato EditPlaceController che raccoglie i dati modificati in una struttura di dati EditPlaceRequest e li passa a EditPlaceInteractor. ecc.

È stato chiesto specificamente il GUID del pin. Questo sarebbe creato dall'entità Place e restituito a PlacePinInteractor editPlacePresenter.

+0

Forse non ero molto chiaro, ma quello che pensavo era: il clic accade nel MapPresenter, ma il posto viene creato solo più tardi, se l'uso preme "done" in PlaceDetailsViewController (che è come la vista). Quando l'utente fa clic su "done", il posto viene creato. Se l'utente fa clic su "indietro", dovrebbe tornare a MapPresenter e quindi non eliminare il pin (o chiuderlo se non è stato creato). –

+0

Per stato intendo cose come il pin che è stato temporaneamente creato nella mappa. In questo modo, quando torniamo da PlaceDetailsViewController/Presenter, sappiamo quale pin eliminare o mantenere (e dare al GUID l'associazione con). –

+0

Pensa a "fatto" e "indietro" come diversi casi d'uso (diversi interattori). –

0

In puro VIPER Router deve contenere i moduli immessi sotto forma di un protocollo. E i moduli Presenter dovrebbero conformarsi ad esso. Quindi quando il Router usa altri moduli Router per assemblare un nuovo modulo, passa il suo input ad esso.

Il secondo router assegna quindi l'ingresso alla sua uscita Presenter. Quindi, in sostanza, Presenter del primo modulo diventa un delegato per il secondo modulo Presenter.

Quindi nel tuo caso quando un utente seleziona un luogo, MapPresenter richiede a MapInteractor un GUID e indica a MapRouter di accedere ai dettagli di questo GUID.

MapRouter richiede a PlaceDetailsRouter di assemblare PlaceDetailsModule per questo GUID e trasferisce MapModuleInput su di esso. PlaceDetailsRouter assegna MapModuleInput a PlaceDetailsPresenter. PlaceDetailsRouter mette GUID nel PlaceDetailsInteractor

Problemi correlati