Grube modele i chude kontrolery brzmią jak tworzenie modeli Boga [zamknięte]

91

Czytałem wiele blogów, które opowiadają się za grubymi modelkami i chudymi kontrolerami , szczególnie. obóz Railsów. W rezultacie routery po prostu zastanawiają się, jaką metodę wywołać na jakim kontrolerze, a cała metoda kontrolera polega na wywołaniu odpowiedniej metody na modelu, a następnie wyświetleniu widoku. Mam tutaj dwie obawy, których nie rozumiem:

  1. Kontroler i router tak naprawdę nie wykonują innych zadań poza wywołaniem metody opartej na modelu boskim na podstawie trasy.
  2. Modelki robią za dużo. Wysyłanie e-maili, tworzenie relacji, usuwanie i modyfikowanie innych modeli, kolejkowanie zadań itp. W zasadzie teraz masz obiekty podobne do Boga, które mają robić wszystko, co może, ale nie musi, dotyczyć modelowania i postępowania z danymi.

Gdzie wyznaczasz granicę? Czy to nie jest po prostu zgodne z wzorem Boga?

Łowca dżungli
źródło

Odpowiedzi:

136

To może nie być najlepszy pomysł, aby spojrzeć na Railsy jako podstawę wzorca projektowego MVC. Wspomniany szkielet został stworzony z pewnymi nieodłącznymi niedociągnięciami (opisałem go w innym poście ), a społeczność dopiero teraz zaczęła zajmować się opadem. Możesz spojrzeć na rozwój DataMapper2 jako pierwszy duży krok.

Trochę teorii

Wydaje się, że osoby udzielające tej rady są dotknięte dość powszechnym błędnym przekonaniem. Zacznę więc od wyjaśnienia: Model we współczesnym wzorcu projektowym MVC NIE jest klasą ani obiektem. Model jest warstwą.

Podstawową ideą wzorca MVC jest Separacja problemów, a pierwszym krokiem jest podział na warstwę prezentacji i warstwy modelu. Podobnie jak warstwa prezentacji dzieli się na kontrolery (instancje odpowiedzialne za obsługę danych wejściowych użytkownika), widoki (instancje, odpowiedzialne za logikę interfejsu użytkownika) i szablony / układy, tak również warstwa modelu.

Główne części, z których składa się warstwa modelu, to:

  • Obiekty domeny

    Znane również jako jednostki domeny, obiekty biznesowe lub obiekty modeli (nie podoba mi się ta druga nazwa, ponieważ po prostu zwiększa zamieszanie). Struktury te są zwykle mylnie określane jako „modele”. Są odpowiedzialne za zawarcie reguł biznesowych (cała matematyka i walidacja dla określonej logiki jednostki domeny).

  • Abstrakcje dotyczące pamięci masowej:

    Zwykle implementowane przy użyciu wzorca mapowania danych (nie mylić z ORMami , które nadużyły tej nazwy). Te instancje zwykle mają za zadanie przechowywanie i pobieranie informacji do obiektów domeny. Każdy obiekt domeny może mieć kilka maperów, tak jak istnieje kilka form przechowywania (DB, pamięć podręczna, sesja, pliki cookie, / dev / null).

  • Usługi:

    Struktury odpowiedzialne za logikę aplikacji (czyli interakcję między obiektami domeny i interakcję między obiektami domeny i abstrakcji pamięci masowej). Powinny działać jak „interfejs”, przez który warstwa prezentacji współdziała z warstwą modelu. To jest zwykle to, co w kodzie podobnym do Railsów trafia do kontrolerów.

Istnieje również kilka struktur, które mogą znajdować się w przestrzeniach między tymi grupami: DAO , jednostki pracy i repozytoria .

Aha ... i kiedy mówimy (w kontekście sieci) o użytkowniku, który współdziała z aplikacją MVC, to nie jest on człowiekiem. „Użytkownik” to w rzeczywistości Twoja przeglądarka internetowa.

A co z bóstwami?

Zamiast mieć jakiś przerażający i monolityczny model do pracy, kontrolery powinny współdziałać z usługami. Przekazujesz dane wprowadzone przez użytkownika do określonej usługi (na przykład MailServicelub RecognitionService). W ten sposób kontroler zmienia stan warstwy modelu, ale odbywa się to za pomocą przejrzystego API i bez bałaganu w strukturach wewnętrznych (co spowodowałoby nieszczelną abstrakcję).

Takie zmiany mogą albo wywołać natychmiastową reakcję, albo wpłynąć tylko na dane, których instancja widoku żąda z warstwy modelu, lub jedno i drugie.

Każda usługa może współdziałać z dowolną liczbą (choć zazwyczaj jest to tylko kilka) abstrakcji obiektów domeny i pamięci. Na przykład RecogitionServicenie mogliby mniej przejmować się abstrakcyjnymi danymi dotyczącymi przechowywania artykułów.

Uwagi końcowe

W ten sposób otrzymujesz aplikację, która może być testowana jednostkowo na dowolnym poziomie, ma niskie sprzężenie (jeśli jest poprawnie zaimplementowana) i ma jasno zrozumiałą architekturę.

Pamiętaj jednak: MVC nie jest przeznaczony do małych aplikacji. Jeśli piszesz stronę księgi gości przy użyciu wzorca MVC, robisz to źle. Ten wzorzec jest przeznaczony do egzekwowania prawa i porządku w zastosowaniach na dużą skalę.

Ten post może być odpowiedni dla osób, które używają PHP jako języka podstawowego . To nieco dłuższy opis warstwy modelu z kilkoma fragmentami kodu.

tereško
źródło
Bardzo przydatna i pełna odpowiedź! Czy znasz jakąś książkę, która wyjaśnia nieco bardziej wzorzec architektoniczny MVC? Szczególnie jeśli chodzi o model, wszyscy błędnie myślą: „Model reprezentuje dane i nie robi nic innego”. a to brzmi bardziej jak idea obiektu domeny, a nie „Model” -> tomdalling.com/blog/software-design/…
thermz
1
@thermz, AFAIK , istnieje naprawdę nie ma książek, które zajmują się wyłącznie z wzorca MVC. Zwykle po prostu mówię ludziom, aby przeczytali PoEAA , a następnie poszperali . Może ta lista linków będzie przydatna. Uważam, że kiedy ludzie dobrze poznają zasady i koncepcje OOP, wzór staje się dość łatwy do zrozumienia.
tereško
@ tereško piękna odpowiedź. Czy Hibernate to osiąga? Nie przekonują mnie odpowiedzi tutaj -> stackoverflow.com/questions/1308096/…
Ankan-Zerob
@ Ankan-Zerob, jak możesz zauważyć, nie jestem programistą Java, ale z tego, co wiem o Hibernate, zapewnia kompletny zestaw narzędzi dla warstwy trwałości. Da ci to część tego, co tam opisano, ale nie pełną warstwę modelu.
tereško
3
@johnny nie tak daleko, jak wiem. Większość tak zwanych "frameworków mvc" w PHP to odmiany Railsów. W ramach kursu większość z nich zawiera pewne rozwiązania ORM oparte na aktywnych rekordach (te rzeczy są notorycznie wrażliwe na zmiany w bazie danych). Państwo może zaimplementować coś takiego z SF2.x lub ZF2.x, ale punkt ram nie jest do wdrożenia / wymusić konkretną architekturę ale dostarczenie narzędzi. Ponadto, jeśli chodzi o MVC, jest on implementowany przez kod aplikacji, a nie framework.
tereško
5

Jeśli klasy „modelowe” są słabo zaimplementowane, tak, twoja obawa jest istotna. Klasa modelowa nie powinna wykonywać poczty elektronicznej (zadania związane z infrastrukturą).

Prawdziwe pytanie brzmi, co oznacza modelowanie w MVC. Nie ogranicza się do klas POCO z kilkoma metodami. Model w MVC oznacza logikę danych i biznesową. Traktuj to jako nadzbiór klasycznych podstawowych modeli POCO.

Widok ==== Kontroler ==== Model ---> Warstwa procesów biznesowych -> Modele podstawowe

Wrzuć zestawy infrastruktury i warstwy dostępu do danych i użyj wstrzyknięcia, aby przekazać to do BPL, a Twój proces używa MVC zgodnie z przeznaczeniem.

BPL może wywoływać wzorce UoW / repozytorium, wykonywać reguły biznesowe i wywoływać funkcje infrastruktury za pomocą wstrzykniętych obiektów lub wzorców interfejsów.

Dlatego zalecenie, aby kontroler był chudy, nie oznacza, że ​​klasa „person” w klasycznym modelu Core powinna mieć 50 metod i bezpośrednio wywoływać Email. Masz rację, myśląc, że to źle.

Nadal może być wymagane, aby kontroler utworzył wystąpienie i wstrzyknął klasy infrastruktury do warstwy BPL lub warstwy rdzeniowej, jeśli zostanie wywołana bezpośrednio. Powinna istnieć warstwa biznesowa lub przynajmniej klasy koordynujące wywołania w klasach klasycznego modelu obiektów. Cóż, to i tak mój "widok" ;-)

Ogólne podejście do MVC opis wiki http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

Mały blog, który mówi o „M” w MVC. http://www.thedeveloperday.com/skinny-controllers/

phil soady
źródło
1
Jeśli się nie zgadzasz, bądź przynajmniej na tyle uprzejmy, aby uzasadnić swój pogląd
phil soady
-1

Myślę, że można dokonać rozróżnienia między jednym grubym modelem (prawdopodobnie nazwanym aplikacją lub aplikacją) a kilkoma modelami grubymi podzielonymi na logiczne grupy (biznes, klient, zamówienie, wiadomość). To ostatnie dotyczy struktury moich aplikacji, a każdy model z grubsza odpowiada tabeli bazy danych w relacyjnej bazie danych lub kolekcji w bazie danych dokumentów. Te modele obsługują wszystkie aspekty tworzenia, aktualizowania i manipulowania danymi, które tworzą model, niezależnie od tego, czy jest to komunikacja z bazą danych, czy wywołanie interfejsu API. Sterownik jest bardzo cienki, odpowiedzialny za niewiele więcej niż wywołanie odpowiedniego modelu i wybranie szablonu.

Bryan Young
źródło