Czy MVC nie chroni przed OOP?

61

Główną ideą OOP jest ujednolicenie danych i zachowania w jednym obiekcie - obiekcie. W programowaniu proceduralnym istnieją dane i osobno algorytmy modyfikujące dane.

We wzorcu Model-Widok-Kontroler dane i logika / algorytmy są umieszczone w odrębnych jednostkach, odpowiednio model i kontroler. W równoważnym podejściu OOP nie należy umieszczać modelu i kontrolera w tej samej jednostce logicznej?

m3th0dman
źródło
11
Dlaczego mieliby być w tej samej logicznej jednostce? Nie podałeś, dlaczego byłoby to korzystne, ani dlaczego OOP dyktuje ten układ.
Robert Harvey
26
Cóż, logika biznesowa dotyczy modelu, a nie kontrolera. Kontroler jest naprawdę tylko pośrednikiem, aby skleić widok i model. Tak więc w modelu masz dane i zachowanie w tym samym miejscu.
Robert Harvey
2
Co? Ujednolicenie danych i zachowania jest dokładnie tym, o co chodzi w OOP.
Andy,
3
OOP polega na oddzielaniu implementacji od interfejsów. Interfejsy mają więcej wspólnego z zachowaniem, a implementacje z danymi (dlatego dane są zwykle ukryte). OOP nie polega więc na ujednolicaniu danych i zachowań, ale na ich rozdzielaniu.
Kaz.
5
W każdym razie nie chcesz upychać wszystkich danych i zachowań w jednej klasie. Programy OOP używają więcej niż jednej klasy do tworzenia struktur obiektów. W każdym razie, jeśli coś jest „anty-OOP”, może to być dobra rzecz. OOP to nie wszystko. OOP wręcz do bani. Czas przejść przez OOP.
Kaz.

Odpowiedzi:

44

MVC to ćwiczenie w zakresie separacji problemów , architektura interfejsu użytkownika. Jest to sposób na wyrównanie złożoności, która może wystąpić w interfejsach użytkownika, ponieważ prezentacja nie jest oddzielona od treści .

Teoretycznie wszystkie obiekty mogą mieć zachowanie, które działa na danych w nich zawartych , a dane i zachowanie pozostają zamknięte . W praktyce dany obiekt OOP może, ale nie musi mieć logiki odpowiadającej jego danym, lub może nie mieć żadnej logiki ( na przykład Obiekt Transferu Danych ).

W MVC logika biznesowa wchodzi w model, a nie w kontroler. Kontroler jest naprawdę tylko pośrednikiem, aby skleić widok i model. Tak więc w modelu możesz mieć dane i zachowanie w tym samym miejscu.

Ale nawet takie rozwiązanie nie gwarantuje ścisłego połączenia danych / zachowań. Obiekty zawierające tylko dane mogą być obsługiwane przez inne klasy zawierające tylko logikę, i jest to całkowicie dopuszczalne użycie OOP.


Dam ci konkretny przykład. Jest to nieco wymyślone, ale powiedzmy, że masz Currencyobiekt, który może reprezentować się w dowolnej dostępnej walucie powiązanej z dolarem. Więc masz metody takie jak:

public decimal Yen { get { return // dollars to yen; } }
public decimal Sterling { get { return // dollars to sterling; } }
public decimal Euro { get { return // dollars to euro; } }

... i takie zachowanie byłoby zawarte w obiekcie Currency.

Ale co, jeśli chcę przelać walutę z jednego konta na drugie lub wpłacić jakąś walutę? Czy takie zachowanie byłoby również zawarte w obiekcie Currency? Nie zrobiłby tego. Pieniądze z twojego portfela nie mogą przelać się z twojego portfela na twoje konto bankowe; potrzebujesz jednego lub więcej agentów (bankomat lub bankomat), aby pomóc w uzyskaniu tych pieniędzy na swoje konto.

Tak że zachowanie będzie zamknięta do Tellerobiektu, a byłoby to zaakceptować Currencyi Accountobiektów jak wejść, ale nie zawiera żadnych same dane, z wyjątkiem może trochę stanu miejscowego (a może Transactionobiektowego), aby pomóc przetwarzać obiekty wejściowe.

Robert Harvey
źródło
A w jakim podmiocie / paczki należy Tellerumieścić? W Controllerskąd Teller'smetody nazywane są albo w Modelbo to jest część logiki biznesowej?
m3th0dman
Tellerwchodzi w Model, chociaż można go wywołać z kontrolera. Jest częścią domeny biznesowej.
Robert Harvey
Zawsze myślałem, że użycie Modelu dla reguł biznesowych sprawia, że ​​MVC jest półefektywnym wzorcem. Używanie modelu dla adapterów do rzeczywistej aplikacji i utrzymywanie przez kontrolery pośredniczenia między adapterami a widokiem jest zawsze znacznie bardziej skuteczne w osiągnięciu SoC.
Yam Marcovic,
@YMMarcovic: Nie jestem pewien, co masz na myśli. Model jest czymś w rodzaju całości; w praktyce reguły biznesowe są zazwyczaj umieszczane we własnej warstwie usług, ale nadal są uważane za część modelu (na przykład nie kodowałbyś określonych reguł biznesowych w ramach metody indywidualnego kontrolera). Masz rację, że kontrolery są pośrednikiem.
Robert Harvey,
4
Jedną rzeczą, którą myślę, że większość ludzi myli się co do MVC po prostu czytając o tym, to zbyt ogólne założenia na temat tego, co oznacza „logika biznesowa”. Jeśli nie możesz wyskoczyć z modelu i używać go z minimalną lub żadną modyfikacją w zupełnie nowej aplikacji, która będzie miała te same cele biznesowe, ale zupełnie inną architekturę za pośrednictwem kontrolera z zupełnie inną logiką aplikacji, robisz to źle IMO. Oczywiście wciąż jest wartość oddzielania poglądów od dowolnej mieszanki wszystkiego, co masz, ale C jako lekka konstrukcja wydaje mi się brakować kluczowego punktu oddzielenia.
Erik Reppen,
73

MVC działa na znacznie wyższym poziomie abstrakcji niż pojedyncze obiekty, aw rzeczywistości każdy z trzech (model, widok i kontroler) zazwyczaj składa się z wielu obiektów, z których każdy ma zarówno dane, jak i zachowanie.

To, że obiekty enkapsulujące dane i zachowanie są dobrym podstawowym elementem składowym programów w ogóle, nie oznacza, że ​​jest to najlepszy wzorzec na wszystkich poziomach abstrakcji i do wszystkich celów.

Michael Borgwardt
źródło
Podejście obiektowe może być skalowane na poziomie abstrakcji; zobacz na przykład powód powstania Domain Driven Design, który pojawił się, ponieważ klasyczna architektura warstwowa nie jest OOPish, ale raczej proceduralna. Dzieje się tak na wyższym poziomie abstrakcji niż MVC.
m3th0dman,
6
@ m3th0dman: Mówisz szerokimi, ogólnymi ogólnikami. Co powiesz na omówienie szczegółów, na przykład tego, jak MVC eliminuje koszmar z kodem spaghetti, jakim są Winforms lub Webforms?
Robert Harvey
3
@ m3th0dman: to dość uproszczona charakterystyka DDD.
Michael Borgwardt,
1
@RobertHarvey Aby upewnić się, że jesteś kontrapunktem, dlaczego MVC jest dobry, ponieważ eliminuje spaghetti, tak naprawdę nie jest tu przedmiotem rywalizacji. Zgadzam się, ale mam tendencję do tego, aby MVC wdrażano również zgodnie z procedurami. Myślę więc, że należy zadać odpowiednie pytanie, a raczej pytanie: „Jak często ludzie wdrażają MVC proceduralnie?”
Jimmy Hoffa,
1
@Robert Harvey Celem tego pytania nie jest to, jak dobry lub zły jest MVC; chodzi o fakt, że opiera się lub nie na zasadach OO.
m3th0dman,
71

OOP nie ogranicza interakcji między obiektami, z których każdy ma własne dane i własne zachowanie.

Pomyśl o analogii mrówek i kolonii mrówek: zachowanie pojedynczej mrówki (bieganie przez cały dzień, dostarczanie jedzenia) różni się od zachowania całej kolonii (znajdź najbardziej pożądane miejsce, zrób więcej mrówek). Wzór MVC opisuje pożądaną strukturę społeczną kolonii mrówek, podczas gdy OOP kieruje projektowaniem poszczególnych mrówek.

dasblinkenlight
źródło
5
+1: Zazwyczaj nie lubię wyjaśnień za pomocą analogii, ale to jest genialne.
Michael Borgwardt,
@Caleb To jest doskonały punkt, bardzo dziękuję!
dasblinkenlight,
19

OOP polega także na oddzieleniu problemów , czyli na oddzieleniu różnych ról / odpowiedzialności w różnych obiektach.

MVC dzieli się na następujące elementy:

  • Model: dane i logika biznesowa
  • Widok: reprezentacja danych
  • Kontroler: koordynacja między modelem a widokiem.

Tak więc te obowiązki są wyraźnie odrębne i rzeczywiście powinny być podzielone na wiele podmiotów.

marco-fiset
źródło
To prawda, że ​​zasada pojedynczej odpowiedzialności jest pomocna w efektywnym korzystaniu z OOP, ale myślę, że trudno jest powiedzieć, że „OOP dotyczy także zasady pojedynczej odpowiedzialności”. To wydaje się zacofane.
Caleb
@Caleb Tak, rozumiem, co masz na myśli. Może może być przeformułowany, ale masz rację.
marco-fiset
18

We wzorcu Model-Widok-Kontroler dane i logika / algorytmy są umieszczone w odrębnych jednostkach, odpowiednio model i kontroler.

Model i kontroler to dwie odrębne role. Model ma zarówno stan, jak i logikę, a kontroler ma zarówno stan, jak i logikę. Fakt, że się komunikują, nie przerywa enkapsulacji żadnego z nich - kontroler nie wie ani nie obchodzi, w jaki sposób model przechowuje swoje dane lub co robi z danymi, gdy kontroler pobiera lub aktualizuje ich część. Model nie wie ani nie obchodzi, co robi kontroler z danymi dostarczanymi przez model.

Pomyśl o tym w ten sposób: jeśli obiekty nie mogłyby przesyłać danych tam iz powrotem bez przerywania enkapsulacji, naprawdę możesz mieć tylko jeden obiekt!

W równoważnym podejściu OOP nie należy umieszczać modelu i kontrolera w tej samej jednostce logicznej?

MVC to podejście OOP - konkretnie, jest to przepis na decyzję o tym, jak używać obiektów do efektywnej organizacji programu. I nie , model i kontroler nie powinny być tym samym bytem. Kontroler umożliwia separację między modelem a widokiem. Zachowanie niezależności modelu i widoku czyni je zarówno bardziej testowalnymi, jak i wielokrotnego użytku.

Caleb
źródło
Chciałbym mieć nadzieję, że kontroler ma logikę, ale niewiele do stanu. Jak myślisz, jaki stan ma kontroler?
Matthew Flynn,
1
@MatthewFlynn Na początek kontroler musi wiedzieć o widoku i modelu. Poza tym może zależeć od tego, o jakim konkretnym smaku MVC mówimy, ale ogólnie kontroler może utrzymywać stan związany z tym, w jaki sposób powinny być wyświetlane informacje (np. Bieżący wybór), podczas gdy model zajmuje się tym, jakie informacje są wyświetlane.
Caleb,
1
@MattFenwick To właśnie mam na myśli o „smaku” ... Dokładnie to, co przechowujesz w kontrolerze, a co w modelu, jest kwestią smaku i konwencji. W Cocoa / Cocoa Touch często kontroluje się takie rzeczy, jak bieżący wybór, a nawet preferencje użytkownika. MVC stosowane w niektórych frameworkach internetowych może umieścić prawie wszystko w modelu, a bardzo mało w kontrolerze. YMMV.
Caleb,
4
@MatthewFlynn Większość zgodzi się z tobą, ale IMO, ludzie uważają logikę biznesową za szerszą kategorię, niż powinna. Kontroler obsługuje logikę aplikacji, którą ludzie często mylą z logiką biznesową. W idealnej separacji problemów powinienem móc ponownie użyć obiektu modelowego w zupełnie innej architekturze aplikacji obsługującej te same cele biznesowe bez modyfikacji obiektu biznesowego. Nowa aplikacja musi tylko korzystać z interfejsu i robić swoje, zwracając i przetwarzając dane i transakcje.
Erik Reppen,
1
@MattFenwick: Zastanów się nad aplikacją dla wielu użytkowników. Oczywistym punktem do narysowania linii między modelem a kontrolerem jest to, że model obsługuje stan współdzielony, a kontroler stan lokalny. Aktualny wybór jest lokalny, więc przechodzi do kontrolera.
Jan Hudec
4

MVC to wzorzec opisujący rozsądny sposób interakcji obiektów; sama w sobie nie jest meta-klasą. W tym przypadku OO polega na opisywaniu zachowań i danych bytów oraz na tym, jak te byty wchodzą w interakcje. Nie chodzi o zjednoczenie całego systemu w jeden masywny obiekt.

Jonathan Weatherhead
źródło
2

Kontroler nie reprezentuje zachowania modelu. Kontrolery w całości reprezentują zachowanie całej aplikacji - co użytkownik może zrobić i co może zobaczyć.

Błędem jest postrzeganie kontrolerów i modeli jako jednego. Mają różne cele, inną semantykę i dlatego nie powinny być zjednoczone w jednym obiekcie.

superM
źródło
2

Warstwa modelowa to nie tylko dane, ale warstwa kontrolera jest jedynie logiką.

Warstwa kontrolera będzie miała pełną kolekcję obiektów do swoich celów. Będą obiekty do odbierania danych wejściowych z widoku i przekształcania tych danych wejściowych do postaci, którą model może przetworzyć. Framework Struts Java ma tego dobry przykład w swoim modelu Action / Form. Formularz jest wypełniany danymi wejściowymi od użytkownika, a następnie przekazywany do akcji. Akcja pobiera te dane i wykorzystuje je do manipulowania modelem.

W ten sam sposób warstwa modelu nie składa się całkowicie z danych. Weźmy na przykład obiekt użytkownika - możesz potrzebować kodu, który pobiera użytkownika z bazy danych, lub kodu, aby powiązać użytkownika z zamówieniem lub sprawdzić, czy adres użytkownika znajduje się w obszarze usług Twojej firmy ... obrazek. To nie jest logika kontrolera. Jest to logika biznesowa i doprowadziło wielu do podzielenia warstwy modelu na kilka warstw, takich jak warstwy usługi lub menedżera dla logiki biznesowej, warstwa DAO (obiekt dostępu do bazy danych) dla dostępu do bazy danych i inne.

MVC nie jest metodą organizowania poszczególnych operacji modelu. Działa na wyższym poziomie - jest to metoda organizacji dostępu do aplikacji. Widok służy do przedstawiania danych i czynności wykonywanych przez ludzi w celu manipulowania nimi, kontroler służy do tłumaczenia między działaniami użytkownika a różnymi widokami, a model jest miejscem, w którym znajdują się dane biznesowe i przyczyny biznesowe.

Michael K.
źródło
2

Celem OOP jest zgrupowanie razem danych i funkcji, które do siebie należą . Obliczenia oparte na niektórych danych nie zawsze należą do tych danych.

W MVC funkcjonalność wyświetlania kawałka danych (widok) jest oddzielona od danych (model). Dlaczego? Jest to specjalnie po to, aby logikę wyświetlania można było zmienić bez konieczności zmiany podstawowych danych. Ułatwia zmianę widoku za każdym razem, gdy trzeba wykonać inną prezentację tych samych danych: lub gdy zmienia się charakterystyka sprzętu wyświetlającego: lub po przejściu z systemu Windows na Linux; lub gdy chcesz, aby dwie osoby miały dwa różne sposoby patrzenia na te same dane.

MVC nie jest w konflikcie z OOP - w rzeczywistości pochodzi z poprawnego zastosowania Zorientowanych Obiektowo Zasad.

DJClayworth
źródło
0

Uważam, że mylisz trwałe dane powiązane z obiektem modelu z danymi aplikacji z baz danych, z którymi model współdziała. Model zawiera logikę biznesową i reguły dotyczące pracy z bazami danych i przeprowadzania transakcji. Może ustawiać i sprawdzać wewnętrzne flagi stanu, takie jak czy dzisiaj jest sprzedaż, czy użytkownik kwalifikuje się do statusu VIP, a następnie odpowiednio rozgałęzić logikę, jeśli chodzi o dostęp, ustawianie lub manipulowanie danymi lub przeprowadzanie zakupu. O tych flagach mówimy, gdy dyskutujemy o obiektach pod kątem enkapsulacji zestawu metod oraz trwałych wartości lub danych.

Tak jak obiekt modelu przechowuje dane w celu ustalenia, jakie reguły biznesowe są w grze, administrator powinien, IMO, trzymać się bardziej ogólnych danych o stanie aplikacji dotyczących zachowania aplikacji, takich jak to, czy użytkownik jest zalogowany czy ma ważny kredyt dane karty w miejscu. Metody modelowe określałyby przede wszystkim stan tych rzeczy, ale kontroler ma sens utrzymywania flag związanych z ogólnym przepływem aplikacji, jeśli nie dotyczą one sposobu prowadzenia działalności lub transakcji danych. Po ustaleniu, że nie są oni zalogowani, nie zawracaj sobie głowy sprawdzaniem stanu użytkownika, dopóki nie okaże się, że podejmowana jest kolejna próba logowania.

Podobnie z odpowiednim obiektem widoku w porównaniu z bardziej typowymi szablonami HTML, które można zobaczyć w większości platform WWW po stronie serwera. Po załadowaniu preferencji kolorów użytkownika powinien to być widok, który przechowuje te dane i wykonuje je. Ładowanie, sprawdzanie poprawności i zmiana ustawień to wszystkie problemy z modelem, ale powinny to być problemy z modelem tylko raz, aż do wprowadzenia zmian.

IMO, nic nie mówi, że kontrolery nie mogą być obiektami złożonymi z widokami i modelami jako wewnętrznymi obiektami agregującymi. Ma to sens, jeśli zastosujesz MVC na mniejszą skalę, jak fabryka widgetów interfejsu użytkownika, ponieważ kontroler jest idealnym miejscem do udostępnienia interfejsu obiektom aplikacji wyższego poziomu, jednocześnie zakopując dane i szczegóły logiczne dotyczące interakcji widoku i modelu. Nie ma to jednak sensu w przypadku monolitycznych obiektów aplikacji, w których kontroler jest naprawdę obiektem najwyższego poziomu.

Erik Reppen
źródło
0

Tak jak rozumiem; Argumentem jest architektura oparta na komponentach a OOP. I nie wdając się w wojnę religijną, myślę, że obaj opisują to samo; tylko patrzę na to z różnych punktów widzenia.

Na przykład, celem OOP / OOD jest uczynienie kodu bardziej modułowym i wielokrotnego użytku. Tak?

Co jest dokładnie celem architektury opartej na komponentach. Są więc bardziej podobni niż cokolwiek innego.

Myślę, że MVC jest tylko naturalną ewolucją OOP i śmiem to powiedzieć; lepszy sposób na uporządkowanie obiektów, oddzielenie problemów i ponowne użycie kodu.

djm
źródło
Powiedziałbym, że MVC i architektura oparta na komponentach to wzorce projektowe, które nie wykraczają poza sferę podejść OOP, podczas gdy OOD / OOP jest po prostu zbiorem pomieszania i zderzenia szkół myśli i malakademii z tym, jak używać graniczącego z wszechobecnym programowaniem konstruować poprawnie. Porównywanie dwóch kategorii rzeczy jest jak porównywanie kwadratów i pisaka, którego użyłeś do narysowania kwadratów.
Erik Reppen,
-1

Spóźniam się na to przyjęcie i biorąc pod uwagę wszystkie odpowiedzi przed moim, przyznaję, że nie mam wiele do zaoferowania. Wydaje mi się jednak, że pytanie nie dotyczy samego wzorca, ale implementacji. MVC samo w sobie nie nadaje się do żadnej konkretnej metodologii. W rzeczywistości mogę łatwo wyobrazić sobie kod zorientowany na procedury we wzorcu MVC (co wydawało mi się, że sugerujesz).

Myślę więc, że prawdziwe pytanie brzmi; czy jesteśmy bardziej podatni na kod proceduralny podczas korzystania ze wzoru MVC.

(a może zdobędę trochę głosów?)

aserwin
źródło
-1

Nie anty, ale także OOP nie jest wymagany dla MVC.

Ponieważ kontrolery, które są zwykle reprezentowane przez klasy, nie przechowują danych. Do czego wystarczyłyby czyste funkcje.

Jeśli przejdziesz dalej i oddzielisz dane od zachowania, powiedzmy na przykład, że modele działają tylko na danych bazy danych, które są pobierane za każdym razem, gdy wywoływana jest ich funkcja (odpowiedzialna za manipulację danymi) (zamiast przechowywania danych w instancji pola) - wtedy możesz powiedzieć to samo dla modeli.

Idąc dalej, jeśli weźmiesz warstwę widoku aplikacji i podzielisz ją w podobny sposób, w rzeczywistości skończysz wnioskiem, że MVC nie ma nic wspólnego z OOP, i jest całkowicie możliwe napisanie implementacji MVC bez żadnego bólu przy użyciu tylko podejścia procedall .

luke1985
źródło
Haha, widzę, że niektórzy ludzie odczuwali ból w obliczu faktów. Za dużo wysiłku, tworząc własne frameworki z OOP? Nie możesz znieść straconego czasu? Najprostsze odpowiedzi są najlepsze.
luke1985
Nie jestem pewien, dlaczego ta odpowiedź ma negatywne opinie. Mówi, że nie są spokrewnieni i nie „anty”. Wydaje się dość dokładne.
mwilcox,
-3

W mojej opinii OOP mają tę wadę, że ponieważ (dane i zachowanie) są uformowane jako jedna jednostka (klasa), to wykazuje więcej efektu sprzęgania niż spójności. Podczas gdy z drugiej strony MVC ma Model zawierający ... (Fasole, DAO, inne klasy logiki), Kontroler określa sposób, w jaki kontrola musi się przemieszczać, a Widoki w celu określenia, w jaki sposób powinny być wyświetlane dane, są podawane osobno. Na tej podstawie bez względu na to, czy projekt jest zbyt duży, aby go przygotować, można go łatwo stworzyć jako odrębny byt inny niż mieszanie się w przeciwieństwie do OOP. Problem rozwiązany jest w logiczny sposób, podobnie jak strategia „dziel i zdobądź”, a MVC postępuje zgodnie z tą zasadą.

użytkownik123790
źródło
czy to tylko Twoja opinia, czy możesz jakoś to zrobić?
komara