MVC (Model-View-Controller) ułatwia organizowanie struktury aplikacji poprzez podział odpowiedzialności na trzy rozdzielne warstwy: widoku (View), kontrolera (Controller) oraz modelu (Model). Warstwa widoku odpowiedzialna jest za sposób prezentacji danych z modelu w interfejsie użytkownika. Warstwa kontrolera obsługuje zdarzenia systemu oraz interakcję użytkownika poprzez delegowanie zadań do modelu oraz powiadamianie widoku o bieżącym stanie. Natomiast warstwa modelu odpowiada za logikę biznesową tzn. za przetwarzanie, przechowywanie i sposób dostarczania danych. Dzięki separacji odpowiedzialności kod staje się bardziej uporządkowany i elastyczny na modyfikacje (zmiana jednej warstwy nie musi pociągać za sobą zmiany kodu w pozostałych warstwach), a warstwa modelu jest zdolna do przeprowadzenia testów. MVC jest bardziej pojęciem konceptualnym niż zbiorem formalnych reguł implementacji.
Ograniczenia
Ze względu na specyfikę architektury systemu Android (cykl życia Aktywności i jej odpowiedzialności) warstwy View oraz Controller są często implementowane w Aktywności przez co nie ma między nimi wyraźnej rozdzielności. Z tego powodu zdolna do przeprowadzenia niezależnych testów jest tylko warstwa Modelu. Implementacja może zostać usprawniona (zgodnie z ideą wzorca) poprzez przeniesienie warstwy View do oddzielnej klasy i pozostawieniu Aktywności odpowiedzialności warstwy Controller. Jednakże takie rozwiązanie jest tylko połowiczne. Wprowadza sztuczny klasowy podział separacji warstw View oraz Controller, ponieważ Aktywność ciągle jest odpowiedzialna za inicjalizacje widoków w warstwie View, które są powiązane z jej cyklem życia. Co więcej warstwa View oraz Controller są zależne od klas Androidowych i mają dostęp do klasy Model, co nadal wpływa na podział odpowiedzialności i możliwości niezależnego testowania. Rozwiązaniem tego problemu może być zastosowanie wzorca MVP.
Użycie
Wzorzec MVC można wykorzystać w małych projektach o niewielkiej ilości ekranów, gdzie ewentualnemu testowaniu podlega przede wszystkim logika biznesowa.
Implementacja
Klasa View inicjalizuje widok oraz realizuje zachowania obiektów widoku, zmiany ich właściwości oraz stanów. View przechowuje referencje do modelu z którego czerpie niezbędne dane do obsługi obiektów widoku. Klasa Controller nadzoruje poprawną obsługę procesów między interakcją użytkownika i systemem. Przechwytuje zdarzenia oraz akcje użytkownika i systemu, deleguje wykonanie zadania do modelu, a następnie powiadamia widok o stanie żądanej akcji. Klasa Model implementuje logikę systemu, a także zarządza danymi.
Poniższy listing przedstawia implementacja wzorca MVC przy zachowaniu klasowej rozdzielności warstw.
Klient inicjalizuje obiekt warstw dzięki czemu stają się one zdolne do współpracy.
Przykład
Ekran wyszukiwania trasy ViewControllerActivity w procesie znajdywania pasażerskiego połączenia kolejowego wykorzystuje komunikacje sieciową. Ponadto zapamiętuje ostatnio poprawanie wprowadzoną stacje początkową i automatycznie uzupełnia polę stacji. Do implementacji tego procesu wykorzystano wzorzec MVC w wariancie połącznej warstwy View-Controller realizowaną przez Aktywność.
Biblioteki
Na pierwszy rzut oka można pomyśleć, że środowisko Android domyślnie implementuje wzorzec MVC, a nawet wymusza na programiścię jego realizacje. Takie przekonanie jest jednak pewnym uproszczeniem. Pomimo dość częstej praktyki traktowania Aktywności jako warstwę View-Controller, warto te warstwy odseparować. Programista implementujący wzorzec powinien pamiętać, że realizacja wzorca MVC jest zależna od architektury systemu, dlatego nie ma jedynej słusznej implementacji.