Dlaczego wszyscy umieszczają kontrolery w jednym folderze, a widoki w innym?

36

Przygotowuję się do wyjścia z aspu do frameworka mvc, asp.net mvc lub nancy. Gdziekolwiek pójdę, widzę foldery na kontrolery / moduły i foldery na widoki. Czy to tylko pavlovski odruch porządkowania według rodzaju, czy może działa głębsza mądrość? Mam mały projekt koncepcyjny, w którym przechowuję razem pliki, które prawdopodobnie otworzę razem, co jest sporym komfortem. Ponieważ pliki te mogą się również nawiązywać, mogą to robić za pomocą krótszych, mniej kruchych linków względnych. Ten wzorzec jest kwestionowany przez mvc, ponieważ ścieżka folderu nie odpowiada już automatycznie ścieżce url, a w asp.net mvc szablony projektu i routing wymuszają views \ controllers \ schism.

Ta strona Microsoft przedstawia koncepcję obszarów. Można to odczytać jako przyznanie, jak niewygodne stają się duże aplikacje z powodu tego sztucznego rozdzielenia.

Ludzie będą sprzeciwić się „rozdzieleniu problemów”, ale oddzielenie problemów już osiągnięto dzięki oddzielnym plikom źródłowym. Wydaje mi się, że nie ma konkretnych korzyści z pobierania tych ściśle powiązanych plików źródłowych i wysyłania ich na przeciwne końce struktury folderów?

Czy ktoś jeszcze z tym walczy? Jakieś wskazówki?

bbsimonbb
źródło
3
Nie uważasz, że logiczne jest oddzielanie plików kodu zaplecza od plików widoku? Jeśli już podążamy w tym kierunku, dlaczego nie umieścić odpowiednich plików CSS i JavaScript w tym samym folderze?
Alternatex
2
Jeśli dostaniesz Resharper, wtedy F12 na wywołaniu do Viewkontrolera przeniesie Cię do widoku, a pierwsza opcja w menu prawym przyciskiem myszy w widoku przeniesie Cię do kontrolera, a cały problem z brakiem nawigacji zniknie.
Pete Kirkham
4
@Alternatex Przykro mi, ale nie rozumiem, w jaki sposób kontroler jest „zapleczem”. Jest ściśle powiązany ze swoimi widokami. Widok nie jest dobry bez kontrolera, kontroler nie ma sensu bez widoku. Pewnego dnia będziesz chciał je usunąć razem. To dla mnie najlepszy test tego, co należy razem w folderze? Chyba że ktoś może mi pokazać lepszy sposób?
bbsimonbb
2
Widoki są warstwą prezentacji. Kontrolery to warstwa zawierająca usługi, które mogą zawierać obiekty z domeny, które zawierają logikę biznesową, a zatem zawierają logikę zaplecza aplikacji. Widoki składają się tylko z trywialnych warunków i prostych pętli do iteracji po kolekcjach, jeśli twoje widoki zawierają coś innego, robisz to źle. Podobnie jak w przypadku zwykłej struktury, oddzieliłeś back-end i front-end, co jest dla mnie lepszą strukturą niż ta, którą sugerujesz.
Andy
10
Więc nie brakuje ludzi, którzy powiedzą mi, że kontroler to zastawa stołowa, więc trafia do szafki na naczynia. Widoki są okularami, więc idą do szklanej szafki. Ja wiem , że kontroler jest naczynia, ale ja proponuje byłoby wspaniale mieć szafkę obiad i kolacja kredens, ponieważ mówimy o rzeczy, które tylko nawyka na obiad lub na kolację.
bbsimonbb

Odpowiedzi:

38

Chciałbym powiedzieć, że to programowanie kultu ładunków , ale istnieją techniczne przyczyny tej struktury. Asp.Net MVC przyjęło konwencję dotyczącą konfiguracji prawie do wszystkiego. Domyślnie silnik widoku Razor przeszukuje Viewskatalog w celu ustalenia , który widok ma zostać zwrócony z kontrolera. Istnieje jednak kilka hacków, aby uzyskać inną strukturę projektu, a Microsoft zapewnia nawet funkcję MVC o nazwie Obszary, która pozwala nam stworzyć bardziej rozsądną strukturę projektu. Możesz także wdrożyć własny silnik widoku , aby określić, gdzie szukać widoków.

Dlaczego mówię, że to programowanie kultu ładunku i że masz rację? Wujek Bob przekonał mnie, że struktura katalogów projektu nie powinna mówić, że jest to aplikacja MVC. Powinien mi powiedzieć, że to front sklepowy, system zgłoszeń wolnych od pracy, czy cokolwiek innego. Struktura i architektura wysoki poziom powinien nam powiedzieć o co to jest to, nie jak to było realizowane.

Krótko mówiąc, uważam, że masz rację, ale każda inna struktura katalogów po prostu walczyłaby z frameworkiem i zaufaj mi, gdy powiem, że nie chcesz próbować zmusić frameworka Asp.Net MVC do robienia czegoś, co nie było nie zostały zaprojektowane. Szkoda, że ​​tak naprawdę nie jest tak konfigurowalny.


Aby szybko rozwiązać problemy architektoniczne, nadal uważam, że modele biznesowe (biznesowe, bez widoku) i DAL powinny znajdować się w osobnym projekcie / bibliotece, która jest wywoływana z aplikacji MVC.

Po prostu kontroler jest bardzo ściśle powiązany z widokiem i prawdopodobnie będzie modyfikowany razem. Wszyscy dobrze jest pamiętać różnicę między sprzężeniem poprzez zależność a sprzężeniem logicznym. To, że w kodzie rozdzielono zależności, nie czyni go mniej logicznie sprzężonym.

Gumowa kaczuszka
źródło
1
Kompleksowy sposób kontrolowania, gdzie brzytwa szuka widoków, znajduje się tutaj . Mogę po prostu wytrwać.
bbsimonbb
3
Obserwowałem wujka Boba, na x1,25, jak sugerowano. To sprawia, że ​​myślę, że gdyby architekci IT budowali budynki, wszyscy mieszkalibyśmy na małych grupach tratw połączonych razem, pływających po jeziorze. Życie niekoniecznie byłoby prostsze.
bbsimonbb
1
To staje się trochę bardziej skomplikowane. Aby naprawdę zlokalizować kontrolery i widoki, musisz rozwiązać ścieżkę widoku w czasie wykonywania, aby uwzględnić przestrzeń nazw kontrolera. Oto jak to zrobić .
bbsimonbb
1
Zobacz także programowanie zorientowane na funkcje ( fosd.net ), będące akademickim odpowiednikiem tego, co opisuje wujek Bob.
ngm
1
Prawo Conwaya w pracy. Jestem pewien, że działa w Twojej firmie @Flater. Standardowy układ MVC działa w wielu firmach, ale nadal wolę grupować rzeczy według semantyki niż składni. Firmy, dla których pracuję, były zorganizowane wokół produktów zamiast ról / funkcji zawodowych. Wierzę, że to jest podstawa moich preferencji tutaj.
RubberDuck
9

Bez względu na przyczynę, jest to zła praktyka. Jest bardzo anty-OO, ponieważ pakiety lub foldery (jakkolwiek chcesz je nazwać) powinny mieć słabe zależności. Klasy (lub pliki) w nich powinny mieć silne wzajemne zależności.

Rzucając wszystkie widoki w jednym folderze i wszystkie kontrolery w innym folderze, tworzysz dwa pakiety z bardzo bardzo ścisłym sprzężeniem. Jest to sprzeczne z zasadą słabych zależności między pakietami.

Widok i kontroler są dwiema połówkami i powinny do siebie należeć. Nie miałbyś jednego losowania szafki dla skarpet po lewej stronie, a drugiego losowania dla skarpet po prawej stronie.

Oliver Watkins
źródło
6

Aby odpowiedzieć na pytanie „Dlaczego wszyscy ...?” pytanie: Oto kilka potencjalnych przyczyn, chociaż nie jestem do końca pewien, która z nich jest prawdziwą przyczyną, ponieważ w rzeczywistości jest to pytanie subiektywne

  • Aby powielić architekturę logiczną (model, widok, kontroler) z pasującym folderem i strukturą przestrzeni nazw

  • Niekonwencjonalne i wygodne, aby postępować zgodnie z szablonem projektu ASP.net MVC

  • Aby pogrupować według przestrzeni nazw, ponieważ Controllers/folder doprowadzi do .Controllersprzestrzeni nazw

  • Może włączyć niektóre scenariusze w DI / IoC, w których klasy kontrolerów są sprawdzane / skanowane tylko z przestrzeni nazw zawierającej / kończącej się na 'Kontrolery' (może to być źle)

  • Aby umożliwić skanowanie szablonów T4 oraz tworzenie modeli rusztowań i kontrolerów w celu generowania widoków

Zawsze możesz stworzyć własną konwencję i postępować zgodnie z nią, jeśli ma to sens dla twojego projektu, nikt cię nie powstrzyma. Ale pamiętaj, że jeśli pracujesz w dużym projekcie i / lub dużym zespole, wówczas domyślna konwencja znana wszystkim może być lepszym wyborem (choć niekoniecznie właściwym!)

Jeśli twoja konwencja jest łatwiejsza do przestrzegania i nie ogranicza produktywności, zrób to z całą pewnością! a może nawet napisze o tym post lub dwa wpisy na blogu, aby spotkać się ze społecznością programistów i uzyskać opinie

Biszoj
źródło
2

Jednym z powodów trzymania widoków i kontrolerów w osobnych katalogach jest to, że programiści i projektanci pracują nad projektem. Możesz uniemożliwić programistom frontonu dostęp do kodu zaplecza (np. W celu zapewnienia zgodności ze standardem PCI, ograniczając dostęp do poufnego kodu).

Innym powodem jest ułatwienie tworzenia „motywów” i wyłączanie wszystkich szablonów poprzez niewielką zmianę ścieżki widoku.

Trzecim powodem jest prosty wzorzec katalogu przy określaniu widoków w frameworku MVC. Łatwiej jest określić podkatalog i plik niż długą długą ścieżkę do każdego widoku.

Jedynym „ciasnym sprzężeniem” powinno być:

  1. Zmienne wysyłane do widoku przez kontroler.
  2. Formularz pól lub działań w widoku, wysyłany z powrotem do kontrolera.

Używam ogólnego kontrolera i staram się zachować nazwy zmiennych w widoku ogólnym, aby wiele widoków mogło używać tego samego kontrolera, a wiele kontrolerów może używać tego samego widoku. Z tego powodu wolę, aby poglądy były całkowicie osobne. Model umożliwia rozróżnienie każdej „rzeczy” w aplikacji - mogą to być obiekty z listą właściwości i metod dostępu / modyfikacji tych właściwości.

W przypadku ściśle sprzężonego kodu rozwiązaniem, które może Ci pomóc, jest umieszczenie wszystkich plików wchodzących w skład pakietu lub „modułu” razem w katalogu z przestrzenią nazw. Następnie możesz użyć skryptu, aby skopiować lub „skompilować” swoje nieprzetworzone szablony do głównego katalogu „views”. Na przykład:


    lib/my-namespace/my-package/
        -> controllers/
        -> models/
        -> views/
            -> theme/
               -> template-name1
    app/compiled_views/theme/
        -> url/path/template-name1

Niestety, jeśli chcesz zmienić strukturę istniejącego motywu, jest więcej tkania w katalogach pakietów i poza nimi, aby zaktualizować widoki.

Weź pod uwagę, że widoki są tylko sposobem formatowania danych, niezależnie od tego, czy są to json, xml, csv, czy html. Jest to szczególnie przydatne, jeśli chcesz, aby aplikacja działała również jako interfejs API. Spróbuj oddzielić widok od danych, używając ogólnych nazw zmiennych, abyś mógł używać tego samego szablonu dla wielu kontrolerów lub modeli (lub użyj, aby zminimalizować ilość kodu, którą musisz zachować).

Frank Forte
źródło
1

Niekoniecznie wszyscy to robią. Na przykład framework Django Pythona ma koncepcję aplikacji, w której podmoduły aplikacji znajdują się we własnych katalogach z własnymi modelami i widokami i szablonami (widoki są w zasadzie tym, co Django nazywa kontrolerami). Zdarza mi się preferować ten sposób robienia rzeczy, ponieważ oznacza to, że mogę łatwo spakować „aplikację” i ponownie użyć jej w różnych projektach, po prostu włączając ją do listy aplikacji w ustawieniach moich projektów. Łatwiej jest również dowiedzieć się, gdzie są różne części. Jeśli spojrzę na plik urls.py i zobaczę coś podobnego url(r'^users/', include('my_site.users.urls')), wiem, że moduł my_site.userszawiera cały kod, który obsługuje użytkowników. Wiem, żeby spojrzeć na moduły my_site.users.viewsi my_site.users.modelskiedy chcę zobaczyć, jak użytkownicy są tworzeni i uwierzytelniani. Wiem, że wszystkie moje trasy są zdefiniowane w my_site.users.url.

Również jeśli jest wystarczająco ogólny, prawdopodobnie mogę użyć tego modułu w innych witrynach, po prostu zmieniając konfigurację lub pakując go jako bibliotekę i publikując jako OSS.

Pavel Penev
źródło
1

Pamiętaj, że jest to zalecany przez Microsoft sposób przechowywania kontrolerów i widoków w innym folderze, więc wiele z nich byłoby zgodne z zalecaną strukturą,

  1. Jednym z powodów może być to, że kontrolery zawsze nie mają relacji jeden do jednego z widokami, szczególnie widoki częściowe mogą być współużytkowane przez kontrolery.
  2. Innym powodem może być wzrost projektu, możesz chcieć przenieść kontrolery i testy jednostkowe do innego projektu (projektów), ale bardzo trudno jest zrobić to samo dla widoków, a widoki / js / css należą do siebie, gdy się nawzajem odnoszą.

Powiedziawszy, że jest wiele postów na temat robienia tego po swojemu, takich jak ten .

Nisko latający pelikan
źródło
„to zalecany przez Microsoft sposób”… Czy możesz wyjaśnić, co masz na myśli? Czy jest na ten temat prawdziwy, autorytatywny artykuł MS? Czy to tylko domyślna konfiguracja projektu dla aplikacji MVC? A jeśli opieracie to na tym drugim, czy nie jest możliwe, że domyślna konfiguracja projektu MVC jest taka, ponieważ tak robią „wszyscy”?
svidgen,
1
Na podstawie artykułu msdn.microsoft.com/en-us/library/… mówi „Kontrolery, które są zalecane” itd. Dla widoków itp.
Low Flying Pelican
0

Dla przypomnienia

Dlaczego mówię, że to programowanie kultu ładunku i że masz rację? Wujek Bob przekonał mnie, że struktura katalogów projektu nie powinna mówić, że jest to aplikacja MVC. Powinien mi powiedzieć, że to front sklepowy, system zgłoszeń wolnych od pracy, czy cokolwiek innego. Struktura i architektura wysokiego poziomu powinna powiedzieć nam o tym, czym jest ta rzecz, a nie o tym, jak została zaimplementowana.

Pytanie: Kto ma dostęp do kodu ?. Programiści. Czy użytkownikom końcowym zależy na kodzie? Nie. A co robi programista, kod. A dokładniej, klasy oparte na typach (kontrolery, usługa, model itd.). Ma to więc sens i łatwo jest debugować kod, jeśli można znaleźć kod oparty na typie kodu, a nie na jego zachowaniu. Plus, powiedzmy, projekt zespołowy, jeden jest odpowiedzialny za kontroler, inny za model, inny dao i inny za widok. Łatwo jest podzielić projekt na części. Dobry kod to kod łatwy do debugowania, a nie kod cukru składniowego. Wujek Bob znowu się myli.

Próba naśladowania zachowania projektu (frontu sklepu) to kult ładunku.

magallanes
źródło
3
Kiedy koduję, najbardziej zależy mi na funkcjach, a nie na typach. Kiedy widzę, że funkcja nie działa zgodnie z oczekiwaniami, wiem, że coś jest nie tak z kodem związanym z tą funkcją, ale niekoniecznie wiem, jaki to typ kodu.
Przestań krzywdzić Monikę
1
„Powiedzmy projekt zespołowy, jeden jest odpowiedzialny za kontroler, inny model, inny dao”. Taki zespół będzie miał trudności z wysyłką czegokolwiek, a kiedy to zrobi, będzie kosztować znacznie więcej kosztów ogólnych i błędów w komunikacji.
RubberDuck
Jak ustalono w łańcuchu komentarzy pod przyjętą odpowiedzią, masz rację, ale tylko w niektórych przypadkach. Gdy firma koncentruje się na projektach MVC, które sprzedaje wielu różnym klientom, utrzymanie struktury MVC ma sens dla ponownego użycia. Kiedy firma koncentruje się na niszy (np. Sklepy internetowe) i być może korzysta z wielu różnych technologii, sensowniej jest mieć strukturę zorientowaną na sklep internetowy. Jest to praktyczne zastosowanie prawa Conwaya . Kod (a zatem i struktura projektu) powinien być zgodny ze strukturą firmy.
Flater
@RubberDuck: Możesz argumentować za dodatkową opłatą w obu kierunkach. Masz rację, że gdy różni ludzie wykonują różne komponenty techniczne, masz lepszą komunikację logiki biznesowej. Jeśli jednak różni ludzie w pełni wdrażają różne funkcje, być może poniesiesz wyższe koszty, upewniając się, że wszyscy są na pokładzie (wykwalifikowani + zgadzają się) z zastosowaniem tego samego podejścia technicznego. Tak czy inaczej, potrzebujesz narzutów komunikacyjnych, aby mieć pewność, że ludzie będą ze sobą współpracować.
Flater
Tak, a przekazywanie zawsze kosztuje więcej niż pojedyncza para programistów implementujących funkcje IME od końca do końca.
RubberDuck