Wzorzec Model-View-Controller (MVC) to klasyczny wzorzec architektoniczny, który pojawił się długo przed Swift i jest używany do rozdzielania danych, interfejsu użytkownika oraz logiki sterującej. W historii rozwoju iOS MVC został ogłoszony przez Apple jako podstawowy wzorzec architektoniczny dla budowania aplikacji w Objective-C i Swift.
Głównym problemem standardowego MVC jest to, że w miarę upływu czasu kontrolery stają się "Masowymi Kontrolerami Widoku", łącząc w sobie logikę biznesową, interakcję z modelem, przetwarzanie wejścia użytkownika, a nawet logikę wyświetlania. Prowadzi to do zmniejszenia czytelności, ponownego użycia i testowalności kodu.
W Swift MVC wdrażane jest z użyciem klas UIViewController dla kontrolera, modeli jako struktur lub klas, oraz UIView do budowania interfejsu. Kontroler łączy model i widok, inicjując aktualizację interfejsu przy zmianach danych.
Przykład kodu:
struct User { let name: String let age: Int } class UserView: UIView { let nameLabel = UILabel() func display(user: User) { nameLabel.text = "\(user.name), \(user.age) lat" } } class UserController: UIViewController { var user: User? var userView: UserView! override func loadView() { userView = UserView() view = userView } override func viewDidLoad() { super.viewDidLoad() if let user = user { userView.display(user: user) } } }
Kluczowe cechy:
Czy można dopuszczać zależności między widokiem a modelem bezpośrednio w MVC?
Nie, widok nie powinien bezpośrednio współdziałać z modelem. Cała komunikacja odbywa się tylko przez kontroler; w przeciwnym razie model "dowiaduje się" o widoku, co narusza zasadę separacji odpowiedzialności i utrudnia skalowanie.
Czy kontroler może zawierać dane i logikę biznesową?
Często błędnie uważa się, że kontroler może zawierać logikę biznesową. W rzeczywistości logikę biznesową należy przenieść do modelu lub osobnych serwisów, a kontroler powinien tylko zarządzać cyklem życia widoku i uzgadnianiem danych.
Jak walczyć z masywnymi kontrolerami (Massive View Controller)?
Aby walczyć z masywnymi kontrolerami, przenieś przetwarzanie danych z kontrolera do modelu lub serwisów, używaj delegatów, wzorców delegacji i kompozycji. Twórz osobne klasy do konfiguracji widoku lub wprowadzaj logikę wyświetlania bezpośrednio w widoku.
W projekcie kontroler przechowywał zarówno dane użytkownika, ich przetwarzanie, jak i kod wyświetlania. Powtórne użycie logiki w innym kontrolerze okazało się niemożliwe, a przetestowanie logiki biznesowej było bardzo trudne.
Zalety:
Wady:
Model odpowiada tylko za dane i logikę biznesową, widok rysuje interfejs, a kontroler je łączy. Pojawiła się możliwość ponownego używania komponentów, testowania i szybszego skalowania aplikacji.
Zalety:
Wady: