MVC – Model

Powstało masę artykułów na temat MVC, temat staje się naprawdę oklepany. Postanowiłem zebrać wszystkie informacje w jedno miejsce i streścić je w jednym artykule uzupełniając go o informacje, które nabyłem z własnego doświadczenia oraz zwracając uwagę na najistotniejsze informacje.

Czym jest model

Model to jedna z warstw wzorca projektowego MVC, który odpowiada logikę biznesową, czyli pozyskiwanie oraz modelowanie danych pozyskanych ze źródła danych. Na samym wstępie brzmi to bardzo abstrakcyjnie. W myśl architektury MVC, dostęp do modelu powinien mieć tylko kontroler, a w żadnym wypadku widok. Dodatkowo model musi pobrać i modelować dane w taki sposób, aby można było go ewentualnie wymienić bez jakiejkolwiek ingerencji w kontroler, a co za tym idzie – widok. Niezależnie od tego, z jakiego źródła informacji korzysta (pliki tekstowe, bazy danych, pliki XML)  kontroler powinien otrzymać maksymalnie zbliżone dane podczas wymiany źródła informacji.

mvc-model

Model != baza danych

Często spotykam się z definicją modelu jako źródłem połączenia i wykonywania zapytań do serwera bazy danych. Otóż nie jest to prawdą. Według ideologii MVC model powinien być jedynie pośrednikiem między warstwą aplikacji przeznaczoną do połączenia do bazy danych, wykonywania zapytań itp., a kontrolerem. Dodatkowo powinien pomóc kontrolerowi w zbudowaniu zapytania do źródła informacji (pobranie danych na podstawie kryteriów), zmodelować je i zwrócić. Dlaczego model nie jest połączeniem do bazy danych? Jeżeli model potraktujemy jako pośrednika między kontrolerem a źródłem danych, ma on prawo wybrać dowolny sposób uzyskania żądanych informacji. Wcale nie oznacza to, że model musi używać baz danych, ale może użyć plików XML lub API udostępniane przez konkretny serwis (np. YouTube)

Wymienialność modeli i modelowanie danych

Modelowanie informacji jest to dostosowanie ich do użytku przez kontroler. Zazwyczaj jest to przekazywanie informacji w postaci tablic, wartości logicznych, liczb i ciągów znaków. Przykładem może być pobieranie informacji z bazy danych. Kontroler de facto nie wie skąd są pobierane dane, wie to tylko model, otrzymuje suche informacje. Jak rozumieć modelowanie danych przy projektowaniu aplikacji? Wyobraźmy sobie sytuację, że zmieniamy źródło informacji z bazy danych na pliki XML. W tym przypadku kontroler powinien otrzymać rekordy danych jako tablica o tych samych kluczach i tych samych typach danych, jak miało to miejsce przy używaniu bazy danych. Wymiana modelu odbywa się bez ingerowania w kontroler.

Przykłady modeli

Najpopularniejszym sposobem pozyskania informacji jest połączenie do bazy danych i pobieranie (reprezentowanie) ich na różnoraki sposób. Doskonale wyjaśnia to tekst znajdujący się w wikipedii:

Frameworki MVC do operacji na bazach danych używają modeli i mapowania relacyjno-obiektowego, ORM (ang. object-relationship mapping) – w Railsach jest to ActiveRecord, w Catalyscie np. DBIx::Class, a framework Spring w Javie używa Hibernate. Zwykle jest też możliwe użycie baz danych przez bezpośrednie zapytania SQL. Użycie modeli upraszcza typowe operacje – wyświetlanie ze stronicowaniem, edycję danych, a także uniezależnia od konkretnego typu bazy danych.

Posiadam przykład od siebie. Źródłem danych jest API serwisu Last.fm:



8 Responses to “MVC – Model”

  1. “W myśl architektury MVC, dostęp do modelu powinien mieć tylko kontroler”

    Nie jest to do końca prawdą. Wieczorem postaram się przedstawić szersza informacje.

    “Model != baza danych”
    Też konkretnie nie określiłeś typu modelu, z tego co pamiętam jest ich parę. Dlatego nie mogę się do końca z tą tezą zgodzić.

    Opisane tutaj elementy są przedstawione od strony “web architektury”, która jest wymuszona naturą requestu http. Należy pamiętać że jak się pisze o MVC należy też pamiętać że jest stosowane w aplikacjach systemowych.

    Piszesz też ze w Modelu zdarza się zmiana źródła danych, w aplikacjach webowych bardzo rzadko do tego dochodzi, niemal nigdy. Dużo częściej zachodzi potrzeba “udekorowania jakoś danych”, lub też “sprzątanie po operacjach”, np: po usunięciu newsa, usunięcie cache.

    Więcej postaram się napisać potem.

  2. ZuLuS says:

    Niestety muszę się nie zgodzić z tym schematem. Wynika z niego że jedyną częścią “świadomą” aplikacji jest kontroler (komunikacja tylko w jedną stronę kontroler->widok), a widok jest jedynie nakładką na otrzymane dane. Co jednak gdy np otrzymamy żądanie wyświetlania newsa, a na stronie wynikowej ma być poza tym info o tym kto jest zalogowany, skróty pozostałych newsów etc…? Kontroler ma się wszystkim zajmować? Jeżeli tak to wymiana widoku implikuje przeróbkę/wymianę kontrolera i tracimy zalety MVC czyli wymienialność komponentów bez wiedzy pozostałej dwójki.

    Ja zawsze stosuję inną zasadę o ile model zajmuje się wymianą danych (ale nie ich validacją, itd..), kontroler ew modyfikuje dane i przekazuje sterowanie do widoku, widok pobiera (nigdy nie modyfikuje) co mu jeszcze jest potrzebne od modelu i zwraca na wyjście (HTML, CLI, XML, PDF etc…). Pozostaje kwestia komunikacji między komponentami ale to już inna bajka (całkiem rozległy temat ;)).

    To tyle moich przemyśleń, temat dosyć rozległy i ciężko go zebrać w prosty sposób bez określenia środowiska w którym chce się go użyć. Sieć web jest dość specyficzna, patrząc na założenia MVC, widok zbyt często miesza się z kontrolerem.

  3. Athlan says:

    @ZuLuS, Widok może pobierać dane z modelu tylko za zgodą kontrolera, czyli tylko wtedy, kiedy do atrybutu widoku zostanie przypisana instancja modelu. Czyli masz rację – widok może korzystać z modelu… ale nie każdego… żeby się nie zapomniał i nie miał przez przypadek dostępu do rekordów użytkownika (hashów haseł) przy wyświetlaniu newsów.

    @hwao, jeżeli chodzi o wymienialność struktur… nie dochodzi do nich często, ale miałem już 2 sytuacje, kiedy trzeba było to zrobić. Lepiej stosować się do wzorca, niżeliby przerabiać połowę aplikacji (kontroler i model, czasem widok);

  4. MWL says:

    Bardzo fajny i przystępny artykuł.. Podstawy podstaw, no ale zawsze ;)

  5. egz says:

    “dostęp do modelu powinien mieć tylko kontroler, a w żadnym wypadku widok”

    Nie tyle (jak HWAO zauważył) nie jest do końca prawdą, co w ogóle prawdą nie jest. Nie rozumiem jednej rzeczy. Dlaczego nadal ludzie pisząc o wzorcach narzucają mocno konkretne ich implementacje? Wzorzec jest… ekhem, WZORCEM, sposobem, pewnego rodzaju trickiem który możemy zastosować w kodzie. To skąd jest wołany model zależy od implementacji – i żeby nie być gołosłownym:

    1. http://martinfowler.com/eaaCatalog/modelViewController.html WIDOK
    2. wystarczy przejrzeć większe rozwiązania dla MVC żeby się przekonać na ile jeszcze sposobów można to organizować

    Reasumując, ja również nie jestem zwolennikiem odwoływania się do modelu z innego miejsca niż kontroler. ALE – nie piszmy ludzią, że inna metoda jest zabroniona, a “ta” to jedyna słuszna, bo to bzdura.

  6. ad4s says:

    najlepiej zrobić benchmark z włączonym buforowaniem output :)(aplikacja www). efekty mogą dać odpowiedź czy warto w widoku operować na modelu

  7. procek says:

    @egz masz rację, ale po to właśnie jest ten wzorzec, aby spróbować się starać go trzymać. Zawsze można zrobić coś inaczej, ale tu chodzi też o to, aby trzymać się konwencji dzięki, której dany program może być rozbudowany przez osoby postronne.

Leave a Reply