2017-03-21 63 views
5

Oto przykładowy scenariusz:Jak udostępniać dane między dwoma prezenterami w architekturze MVP w systemie Android?

Mam aktywności (Widok) i prezenter dla tego widoku. Prezentujący pobiera listę użytkowników z sieciowego interfejsu API i przechowuje je w pamięci przy użyciu obiektu List. Działanie zawiera różne typy fragmentów do wyświetlania treści o użytkownikach na podstawie User.type. Dwa fragmenty (UserType1Fragment i UserType2Fragment) również mają swoich odpowiednich prezenterów.

Prezenter zajęć decyduje, który typ (I lub II) fragmentu jest pokazany na podstawie kolejnych. Prezenterzy fragmentów decydują o sposobie wyświetlania obiektu użytkownika i obsługują zdarzenie click click o nazwie killUser(). Powinno to zaktualizować obiekt List w podglądzie działania.

To gdzie leży problem:

jaki sposób przedstawia fragment mieć odniesienie do danych aktywności prezentera? Prezenterzy nie powinni bezpośrednio komunikować się ze sobą. Może powinienem wyodrębnić List do repozytorium/interaktora? W jaki sposób lista byłaby dostępna dla prezenterów?

+2

Utrzymuj dane za pośrednictwem modelu. To nie jest dokładnie to samo, ale zobacz diagram dodany w tej odpowiedzi - http://stackoverflow.com/a/41966497/568898. Trwałość może być tak prosta, jak zmienna statyczna (ale tego nie zalecam). – Jahnold

+0

@Jahnold Ok, więc zaimplementowałem repozytorium/interaktora, który jest wspólny dla obu prezenterów (czy jest to singleton)? W tym przypadku powiedzmy, że działanie tworzy nowy obiekt interaktora i przekazuje go do nadrzędnego prezentera za pośrednictwem konstruktora. tj. w działaniu: 'onCreate() { mInteractor = new UserInteractor; mPresenter = new Presenter (this, mnternter); } // i fragmentu: onCreateView() { mFragmentType1Presenter = nowy FragmentType1Presenter (. To getActivity() mInteractor); } ' Czy jest to zgodne z zasadą MVP i nie powoduje żadnych problemów? Dzięki. – XenoChrist

+0

Nie używaj interaktora z aktywności w swoim fragmencie. To by ich łączyło. Po prostu użyj osobnej instancji (lub jeśli naprawdę masz do singletona) – Jahnold

Odpowiedz

12

Więc skończyłem wdrażanie czegoś, co zalecane przez @ Jahnold. (Zamieszczę diagram w linku podanym na pomysł stackoverflow.com/a/41966497/568898)

Hannes Dorfmann (facet, który stworzył/zarządza słynną biblioteką MVP Mosby: Github link) również wskazał mi w tym kierunku.

enter image description here

Wykonanie

mam prezenterem głównego działania i wiele fragmentów, które mogą być wykorzystywane w tej czynności. Każdy fragment ma swojego własnego prezentera. Następnie używam repozytorium (wyszukaj wzór repozytorium), który zasadniczo przechowuje modele i logikę biznesową. Dla mojego przypadku użycia, przechowuję to repozytorium jako singleton. Repozytorium udostępnia dane w trzech formach: z api online, bazy danych sqllite lub pamięci podręcznej przechowywanej w pamięci (w zasadzie lista elementów). Mam również niektóre indeksy int currentitem i rzeczy w tym repozytorium, które są aktualizowane na podstawie bieżącego stanu.

W związku z tym dane, stan i logika biznesowa są przechowywane w tym udostępnionym repozytorium. Prezenterzy i widoki są dość głupie. Nie mam dużej logiki biznesowej (logika specyficzna dla aplikacji) w prezenterach. Mają po prostu logikę związaną z tym, jak dane mają być wyświetlane (zobacz konkretną logikę) i preprocessing w logice je.

Przykład

Ilekroć fragment i działalność muszą ze sobą rozmawiać (przez prezenterów), gdy użytkownik kliknie przycisk we fragmencie dziecięcej, fragment prosi swojego prezentera do handleClick, prezenterzy aktualizuje repozytorium currentItemSelected dane (lub coś innego) i prosi fragment, aby wystrzelił zdarzenie (np. onbuttonclick) do odbiornika, który implementuje aktywność. Gdy aktywność otrzyma zdarzenie, prosi o to swojego prezentera, który z kolei będzie szukał aktualizacji w repozytorium, aby pobrać nowy currentItemSelected.

Extra Info (wersja zaawansowana):

Można również śledzić Clean architekturę, która jest jakby bardziej zaawansowanej wersji MVP architektury. MVP po prostu zajmuje się architekturą widoków, gdzie jako czysta architektura zajmuje się również logiką biznesową i architekturą danych, MVP to tylko niewielka część czystego łuku, która służy do obsługi widoków. Dzięki temu możesz podzielić mega repo w moim przypadku na kolejne przypadki użycia (lub interakcje), które obsługują konkretny przypadek użycia logiki biznesowej, a repozytorium właśnie dostarcza dane. Zatem przepływ logiki jest teraz widokiem -> prezenter -> interaktor -> repo iz powrotem.

+2

dzięki za bardzo jasną i opisową odpowiedź! –

+0

@ XenoChrist Dzięki za tę wspaniałą odpowiedź, ale jak zarządzasz wymianą fragmentów w działaniu? Czy robisz co następuje: view (onclick)> prezenter (setFragment) i zapisanie fragmentu w repo> działaniu (setFragment (fragment z repozytorium))? Czy możesz przejść przez prezentera aktywności, aby uzyskać następny fragment i wrócić do działania, aby zastąpić fragment? –

+0

@DavidSeroussi Jeśli weźmiemy pod uwagę właściwe podejście do architektury, prezenter nie powinien być świadomy konkretnych rzeczy związanych z Androidem. Podobnie jak inne części, takie jak repozytoria. W twoim przypadku powinien wyglądać tak: (widok) onClick() wywołuje presenter.onButtonClicked() -> (prezenter) onButtonClicked() wywołuje view.replaceFragment() -> (widok lub twoja aktywność) replaceFragment() wykonaj fragment zastąpienie. Może to wyglądać na zbyt skomplikowane, ale jest to właściwy sposób na przestrzeganie zasad Clean Architecture. –

0

możesz przekazać listę odwołań do fragmentu za pomocą newInstance() fragmentu. Myślę, że prezenterowie nie powinni się ze sobą bezpośrednio komunikować.

Powiązane problemy