Architektura MVC - Ile sterowników potrzebuję?

54

Od dłuższego czasu programuję, ale głównie skrypty i proste aplikacje. Przeszedłem na nową rolę, w której chodzi o tworzenie aplikacji internetowych i korzystanie z odpowiedniej architektury MVC, dlatego desperacko staram się o tym wszystkim dowiedzieć bardzo szybko.

Mam nadzieję, że to pytanie nie jest zbyt podobne do „ Najlepszych praktyk dla architektury MVC ”, ale kiedy przechodzę przez kilka różnych samouczków, zauważyłem, że niektóre mają wiele kontrolerów do różnych rzeczy.

Ile kontrolerów potrzebuje pojedyncza aplikacja internetowa?

Zdaję sobie sprawę, że trudno byłoby odpowiedzieć bez przykładu, więc przedstawię jeden:

Podanie:

  1. Użytkownik loguje się.
  2. Użytkownik może zrobić jedną z trzech rzeczy:
    a) Prześlij plik (przechowywany w bazie danych mongodb z metadanymi).
    b) Wyszukaj plik.
    c) Wyloguj się.

Moje pytanie jest ogólne, ale podałem przykład, aby pomóc każdemu, kto próbuje odpowiedzieć.

Jeff
źródło
8
Naprawdę ładnie zadane pytanie.
Daniel Hollinrake,

Odpowiedzi:

34

Dla twojego przykładu stworzyłbym dwa kontrolery:

  • Sessions Controller for Login and Logout (utwórz i zniszcz sesję dla REST jak układ)
  • Kontroler plików do wszystkiego w plikach (indeks = wyszukiwanie i tworzenie = przesyłanie)

Ogólnie rzecz biorąc, podejście RESTful, w którym myślisz o wszystkim jako o zasobie, który można wyświetlać, tworzyć, edytować i niszczyć, daje ci dobry pomysł na uporządkowanie rzeczy. Jak widać z moich przykładów, nie trzymam się zbyt blisko każdego czasownika w REST.

Najprawdopodobniej będziesz potrzebować więcej kontrolerów dla dalszej funkcjonalności. Na przykład kontroler użytkowników, w którym użytkownicy mogą tworzyć nowe konta. Oprócz tego potrzebujesz interfejsu administratora, w którym możesz edytować zasoby z wyższymi uprawnieniami. W takim przypadku zduplikowanie prawie każdego kontrolera jest dość powszechne.

Bardzo bardzo przybliżone oszacowanie, aby uzyskać wstępny pomysł, może być jednym kontrolerem dla każdej tabeli w bazie danych, do której użytkownicy mają dostęp. Ale to naprawdę tylko bardzo prymitywny pomiar.

Thorsten Müller
źródło
3
Biorąc przykład administratora: czy administrator administratora rozszerzyłby ogólnego użytkownika, czy też całkowicie zdefiniowałby wszystkie metody? Na przykład może wszyscy użytkownicy mogą przesyłać i wyszukiwać, ale tylko administratorzy mogą usuwać. Czy klasa kontrolera administratora odziedziczyłaby wszystkie ogólne metody użytkownika?
Jeff
4
To naprawdę zależy od faktycznej funkcjonalności, ale generalnie po prostu piszę drugi kontroler bez żadnego dziedziczenia. Zgodnie z zasadą „cienkiego kontrolera” i tak nie powinno być dużo kodu w kontrolerze. Kontroler administratora może być szczególnie prosty. Wszystkie ważne funkcje trafiają do modelu. (np jeśli usuwania użytkownika oznacza wszystkie jego pliki powinny być również usuwane następnie model radzi sobie z tym, że nie jest to pojedyncza linia dla tego w kontrolerze)
Thorsten Müller
6

To zależy od aplikacji internetowej. W twoim przykładzie jeden jest prawdopodobnie wystarczający. Jeśli chcesz wdrożyć pełną aplikację e-commerce z wysyłką, podatkami, zarządzaniem zapasami, warstwowymi cenami itp., Możesz chcieć mieć jeszcze kilka.

Jeśli twój kontroler cierpi z powodu jednego lub więcej zapachów kodu (szczególnie Large Class lub God Object ), to wiesz, że prawdopodobnie przekroczysz punkt, w którym wystarczy jeden.

Dan Pichelman
źródło
5

To naprawdę zależy od potrzeb aplikacji i architektury modułów biznesowych.

Ogólna zasada , liczba wymaganych kontrolerów zależy od liczby modułów i podmodułów w aplikacji internetowej.

Jako uzupełnienie pomocne byłoby zorganizowanie kontrolerów w Obszary . Koncepcja Obszarów jest wbudowana w platformę ASP.NET MVC i upraszcza organizację kontrolerów obsługujących jeden moduł.

Istnieje wiele powiązanych dyskusji:

EL Yusubov
źródło
1
Świetne referencje! Na pewno je sprawdzę!
Jeff
Pewnie nie ma problemu.
EL Yusubov,
4

Podoba mi się sposób Apple.

Każdy widok jest kontrolowany przez tylko jeden kontroler widoku. ~ Zobacz Przewodnik programowania kontrolera dla iOS

Chodzi o to, że powinieneś być w stanie łatwo wymieniać Widoki. IMO, mając tylko 1 Controllerna Viewto ułatwia to osiągnąć. Ale jestem pewien, że możesz mieć kontroler z wieloma widokami i nadal go projektować, abyś mógł przełączać widoki bez zmiany logiki programu.

Korey Hinton
źródło
To dobra uwaga, ale czy potrzebujesz kontrolera do każdego widoku i dodatkowych, aby zająć się takimi sprawami jak użytkownicy? Sądzę też, że gdyby mój projekt był większy, sensowniej byłoby mieć więcej kontrolerów.
Jeff
Modele powinny śledzić użytkowników. Dlatego wiele kontrolerów może w razie potrzeby korzystać z tego samego obiektu modelu.
Korey Hinton
2
Zatem kontroler ma obiekt Model i obiekt View. Kontroler prosi obiekt modelu o informacje (takie jak informacje o użytkowniku), a następnie odpowiednio ustawia widok. Model powinien mieć większość logiki programu, podczas gdy kontroler po prostu ma logikę umożliwiającą komunikację tam iz powrotem między widokiem a modelem.
Korey Hinton
2
Jeden kontroler na widok ma bardzo ograniczoną konstrukcję, ponieważ kontroler nie byłby w stanie wyświetlać różnych modeli widoków dla różnych stanów modelu.
EL Yusubov,
1
@ElYusubov Widzę, co może być mylące. W systemie iOS każdy widok ma tylko jeden kontroler widoku, a każdy kontroler widoku ma tylko 1 aktywny widok (i ten widok może mieć pod-widoki), ale ten kontroler widoku może także zawierać odniesienia do dowolnej liczby widoków.
Korey Hinton
2

Jednym z przykładów, które lubię, jest myślenie o termostacie. Termostat to świetny obraz do oglądania wzoru MVC.


Na starszym, analogowym termostacie możesz wyobrazić sobie takie rzeczy:

Widok - czytnik temperatury, który wyświetla aktualną temperaturę.

Kontroler - Pokrętło, w którym zmieniasz temperaturę

Model - części wewnątrz, które są wywoływane przez sterownik, powodujące zmianę temperatury.


Zawsze powinieneś przestrzegać projektów, które umożliwiają luźne łączenie i ograniczanie modeli i powiązanych z nimi kontrolerów do jednego zadania , i powinieneś używać tyle modułów / sterowników, ile potrzebujesz . W zależności od wielkości aplikacji możesz mieć znacznie mniej widoków niż modele i kontrolery. Tego należy się spodziewać w przypadku każdej aplikacji o dużych rozmiarach. Dobre programowanie obiektowe charakteryzuje się luźnym sprzężeniem, enkapsulacją, dziedziczeniem i polimorfizmem. Nie wszystkie języki obsługują polimorfizm w takim samym stopniu (funkcja, metoda, przeciążanie / zastępowanie operatora).

Jeśli chcesz lepiej zrozumieć poprawne stosowanie architektury MVC, zapoznaj się z GoF „Wzorce projektowe: elementy oprogramowania wielokrotnego użytku ...”, które wykorzystują na przykład C ++ i SmallTalk. Ta książka nie jest alfą i omegą, ale na pewno jest to początek!

Powodzenia!

Charles Addis
źródło
1

Zakładam, że twój przykład przekształci się w złożony system.

Podanie:

Użytkownik loguje się:

  • LoginController

Jego wyłączną odpowiedzialnością jest obsługa logowania, przekierowanie użytkownika lub powiadomienie użytkownika o wyniku.

Prześlij plik

  • UploadController

Zakładam, że chcesz przesłać dowolny typ pliku. Jeśli w późniejszym czasie zdecydujesz się przesłać pliki MP3 i PDF, wtedy będę mieć podstawowy UploadController, MP3UploadController i PDFUploadController.

Wyszukaj plik.

  • SearchFileController

To wystarczyłoby dla podstawowego wymogu. Później możesz mieć wiele kontrolerów wyszukiwania w zależności od stopnia skomplikowania logiki wyszukiwania. Ostatnią rzeczą, którą chcesz mieć, jest pojedynczy SearchController z 20 metodami akcji wykonującymi różne wyszukiwania.

Wyloguj.

-LogoutController .

Można uznać, że to przesada, ale nie sądzę, że tak jest. Myślę, że jest czysty i ładnie oddzielony.

Gdybym miał przyjrzeć się tej strukturze projektu, od razu wiedziałbym, co ona robi i jak jest zbudowana. Aby zgłosić się o krok dalej, chciałbym położyć LoginControlleri LogoutControllerdo oddzielnego obszaru.

Opracowałem już coś takiego i działało to naprawdę dobrze.

CodeART
źródło
Dzięki za wkład! Masz jakiś działający kod? utknąć na kilku rzeczach.
Jeff,
Jakie masz problemy?
CodeART
Jestem w stanie przesłać temat i datę (w formacie ciągu), ale nie mogę przesłać samego pliku (patrz stackoverflow.com/questions/18344614/... ).
Jeff
Jestem programistą .NET. Przepraszam, nie mogę ci pomóc.
CodeART
1

Większość twojego kodu dzieje się w warstwie biznesowej, prawda? W takim przypadku wszystko, co naprawdę robisz w kontrolerze, to zwracanie danych do widoku.

Nie jestem pewien, czy jestem fanem rozdzielania kontrolerów na podtypy. Chociaż powinieneś zachować separację obaw, myślę, że podtypy idą trochę za daleko. Należy również zachować ostrożność w przypadkach, gdy ciężkie obiekty są inicjowane w konstruktorze lub kontrolerze. Na przykład: w twoim przykładzie chciałbyś, aby ciężki obiekt, używany tylko do wyszukiwania / przesyłania pliku, został zwolniony, gdy użytkownik jest na stronie logowania.

Lepiej mieć kontroler na jednostkę logiczną, na przykład AccountController (logowanie, rejestracja, wylogowanie), FileController (wyszukiwanie, przesyłanie) i tak dalej.

harsha
źródło
0

Ogólnie można powiedzieć, że każdy MODEL ma własne STEROWNIKI i dedykowane WIDOKI. Mówiąc ogólnie, mam na myśli, że jest to najlepsza praktyka.

Aspekty aplikacji (takie jak zarządzanie użytkownikami) powinny zostać przetłumaczone na usługę aplikacji i muszą być wywoływane przez kontroler samodzielnie lub w celu owinięcia kontrolera (za pomocą atrybutów, które sprawiają, że funkcjonalność kontrolera jest „widoczna” zgodnie z rolą użytkownika żądania).

Pamiętaj, że wszystkie kontrolery powinny zasadniczo obsługiwać operacje CRUD w modelu i używać różnych widoków dla różnych filtrów.

Moim zdaniem jedną z głównych zalet MVC as pattern jest to, że zapewnia najlepszy sposób wiązania modeli i widoków.

O dodanym przykładzie: utworzę 2 kontrolery: jeden do operacji logowania wszystkich użytkowników (rejestracja, logowanie, wylogowanie itp.), A drugi do operacji na plikach (przesyłanie i wyszukiwanie). zwróć uwagę, że pierwszy powinien mieć kopię zapasową z pewnym aspektem związanym z funkcją logowania, a drugi to zwykły kontroler

Saturn Technologies
źródło
bez wyjaśnienia odpowiedź ta może stać się bezużyteczna w przypadku, gdy ktoś inny wyrazi przeciwną opinię. Na przykład, jeśli ktoś opublikuje oświadczenie typu „Zarządzanie rolami użytkowników i autoryzacją nie powinno znajdować się na wierzchu kontrolera” , w jaki sposób ta odpowiedź pomoże czytelnikowi wybrać dwie sprzeczne opinie? Rozważ edycję go w lepszym stanie
gnat
1
@gnat Akceptuję twój komentarz, zobacz zredagowaną odpowiedź
Saturn Technologies