Dobra praktyka dotycząca rozwiązań Visual Studio [zamknięte]

10

Mam nadzieję, że proste pytanie dotyczące względności. Zaczynam pracę nad nowym projektem wewnętrznym, który ma zapewnić wykonalność naprawionych urządzeń w budynkach.

Baza danych jest przechowywana zdalnie na serwerze WWW i będzie dostępna za pośrednictwem interfejsu API sieci Web (wyjście JSON) i chroniona za pomocą protokołu OAuth. Interfejs GUI jest wykonywany w WPF, a kod biznesowy w C #.

Z tego widzę różne warstwy Prezentacja / Aplikacja / Magazyn danych. Będzie kod do zarządzania wszystkimi uwierzytelnionymi wywołaniami do API, klasa reprezentująca byty (obiekty biznesowe), klasy do konstruowania bytów (obiekty biznesowe), części do GUI WPF, części modeli widoków WPF i tak dalej.

Czy najlepiej jest to utworzyć w jednym projekcie, czy podzielić je na pojedyncze projekty?

W moim sercu mówię, że powinno to być wiele projektów. Zrobiłem to wcześniej w obie strony i stwierdziłem, że testowanie jest łatwiejsze dzięki jednemu projektowi, jednak w przypadku wielu projektów rekurencyjne zależności mogą się pojawić. Zwłaszcza gdy klasy mają interfejsy ułatwiające testowanie, zauważyłem, że rzeczy mogą stać się niezręczne.

JonWillis
źródło
1
Oddzieliłbym je od tego, co ma sens dla projektu.
Ramhound,
Czy ktoś jeszcze ma jakieś przemyślenia na temat posiadania interfejsów, jak sugerował MattDavey. Użyłem tego podejścia wcześniej, aby uniknąć wspomnianych zależności. A może interfejsy dla klasy x powinny znajdować się w tym samym projekcie co klasa x.
JonWillis,
Jakich warstw wszyscy używacie. Widziałem kilka różnych odmian, chociaż główne z nich to Prezentacja / Aplikacja / Infrastruktura. Niektóre dzielą również aplikację na 2 części, aplikację + usługę. Niektóre modele wspominają również o określonej warstwie dla logiki biznesowej, która według mnie mogłaby być zawarta w samych obiektach biznesowych.
JonWillis,

Odpowiedzi:

8

To zależy od wielkości projektu

Oto wytyczne, których zwykle używam

  • Mały projekt, z garstką stron lub mniej, prawie zawsze trzymam się jednego projektu.

  • Jeśli warstwa dostępu do danych w małym projekcie jest duża lub złożona, mógłbym ją rozdzielić na osobną warstwę, ale w przeciwnym razie po prostu znajduje się we własnym folderze.

  • Jeśli projekt jest większy, prawie zawsze będę mieć osobny projekt dla DAL, a wszelkie dalsze dzielenie zależy od tego, gdzie leżą granice między funkcjonalnością aplikacji.

  • Jeśli aplikacja ma wiele celów, każdy z własnymi widokami, modelami widoków itp., To zwykle podzielę każdy element na osobny obszar. Jeśli każda sekcja jest niewielka, oddzielam ją folderem. Jeśli każda sekcja jest duża, rozdzielę je według projektu.

  • Jeśli mam wiele projektów, które muszą odnosić się do tego samego zbioru obiektów ( ViewModelBase, RelayCommanditp), będę utworzyć projekt tylko dla współdzielonych obiektów infrastrukturalnych.

  • Jeśli mam dużą liczbę wspólnych niestandardowych stylów / szablonów / zasobów, utworzę projekt tylko dla nich.

Na marginesie, popełniłem błąd przy pierwszym dużym projekcie WPF i oddzieliłem je, umieszczając Modele w jednym projekcie, Widoki w innym, a ViewModels w trzecim. Mogę ci teraz powiedzieć, że nie jest to dobra droga, ponieważ utrzymanie staje się koszmarem :)

Rachel
źródło
Ciekawe, jakie problemy konserwacyjne miałeś, oddzielając warstwy?
Ian
@Rachel, będę używał WPF. Byłbym więc zainteresowany, aby dowiedzieć się, jak zorganizowałeś wtedy projekt. Wydaje mi się, że pamiętam mały projekt MVC, który był trudny przy dzieleniu 3 części na 3 biblioteki dll. W przypadku WPF Moim widokiem będzie GUI, obiekt / obiekt biznesowy, który ma zostać zmieniony, a ViewModel interakcja między nimi. ViewModel radziłby sobie z logiką wywoływania repozytorium w celu załadowania / zapisania napraw (które z kolei mają fabryki / api internetowe itp.).
JonWillis,
1
@Ian Największy problem polegał na tym, że najdrobniejsze zmiany, takie jak dodanie pojedynczego pola, wymagały ode mnie odnalezienia Modelu, Widoku, Modelu i DAL w 4 oddzielnych bibliotekach. Projekt, nad którym wtedy pracowałem, był dość duży i zmarnowałem więcej czasu niż szukałem konkretnych plików. Od tamtej pory zmieniło się do utrzymania obiektów powiązanych ze sobą, więc na przykład coś Search-pokrewne, takie jak SearchView, SearchViewModeli SearchResultModelto wszystko być grupowane w folderze i znalazłem to sprawia, że aplikacja łatwiejsze w utrzymaniu.
Rachel
@Ian pamiętam również problemy z zależnością i cykliczne odwołania, ponieważ pomimo moich najlepszych starań niektóre warstwy musiały odwoływać się do innych, ale ta warstwa odwoływała się do nich, więc miałem brzydkie obejścia, dopóki nie zrefaktoryzowałem
Rachel
1
@JonWillis Większość moich projektów WPF jest podzielonych na podstawie punktów określonych w mojej odpowiedzi. Zwykle DAL jest własną warstwą, a każdy moduł lub sekcja projektu jest pogrupowana razem (we własnym folderze, przestrzeni nazw lub projekcie, w zależności od wielkości projektu). Na przykład wszystkie obiekty wyszukiwania byłyby razem, w tym Interfacedla warstwy danych, ale rzeczywista warstwa dostępu do danych dla wyszukiwania byłaby w bibliotece DAL. Dość często mam bibliotekę Infrastructurelub Commonbibliotekę, która zawiera wspólne klasy podstawowe, interfejsy i klasy pomocnicze.
Rachel
14

Widziałem najlepsze wyniki z jednym projektem na warstwę plus projekt testowy na warstwę. Widziałem kilka aplikacji, których nie można zrealizować w 10 lub mniej projektach w rozwiązaniu, w którym rozwiązanie obejmuje wszystko .

Nie wpadnij w pułapkę korzystania z projektów, w których naprawdę chcesz przestrzeni nazw. Mnóstwo projektów dodaje jedynie koszty ogólne bez żadnego zysku.

Bryan Boettcher
źródło
9

Oddzielny IMHO jest prawie zawsze lepszy. Prawie zawsze oddzielam swoją warstwę danych, chyba że projekt jest w 100% trywialny. Powodem jest to, że warstwa danych ma tendencję do omijania najczęściej. Rzadko podłączasz GUI do wielu warstw danych i oczekujesz, że będzie działał dobrze. O wiele bardziej powszechny scenariusz polega na tym, że masz pojedynczą warstwę danych i chcesz, aby była ona rozproszona na wiele GUI (na przykład ASP.Net, WPF i aplikacja Silverlight). To niesamowite, kiedy możesz po prostu zbudować projekt warstwy danych i umieścić tę bibliotekę DLL jako odniesienie w następnym GUI, który budujesz.

Morgan Herlocker
źródło
+1 Kiedy rozpoczynam nowe projekty, dość często buduję symulowaną warstwę danych, która przechowuje dane w pamięci. Pozwala mi najpierw zacząć budować resztę aplikacji. Potem mogę go później zamienić na „prawdziwą” warstwę dostępu do danych.
MattDavey,
Czy rozważysz byty (DTO), fabryki i klasy używane do komunikowania się z serwerem sieciowym wszystkie części warstwy danych?
JonWillis
@JonWillis - Nie, prawdopodobnie nie wszystkie. Umieściłem fabryki i klasy dla serwera WWW w przestrzeni nazw projektu biblioteki klas. Moja typowa warstwa danych zawiera tylko niezbędne pliki dbml i / lub pliki edmx. Z reguły jednak nadaję elementom „biblioteki / frameworka” własny projekt. Na pewno nie trzeba ich angażować w projekt GUI, chociaż widzę, że ludzie robią to cały czas.
Morgan Herlocker
Realistycznie jednak, ile czasu zajmie ci zajęcie kilku przestrzeni nazw i rozgałęzienie ich w nowy projekt. Czuję, że jest to dość łatwa praca refaktoryzacyjna.
Didier A.
4

Dla mnie 4 * to magiczna liczba. Jeden projekt dla każdej warstwy i jeden projekt, który określa wszystkie interfejsy / DTO potrzebne do komunikacji między nimi.

* 7, jeśli policzysz testy jednostkowe

MattDavey
źródło
2

Zawsze korzystałem z jednego rozwiązania, jeśli pracuję na tych różnych warstwach lub jeśli jest z nimi ściśle związane. Chcę nacisnąć klawisz F5 i w razie potrzeby przebudować wszystkie projekty. Nie wydaje mi się, żeby istniał „właściwy” sposób.

Jeremy
źródło
2

Najważniejszy jest jego osobisty gust . Osobiście mam osobny projekt dla każdej warstwy aplikacji, więc separacja jest oczywista.

Tom Squires
źródło
Do jakich warstw się oddzielasz? Czy masz osobne warstwy aplikacji / usług, a jeśli tak, to czym się właściwie różnią. Czy logika biznesowa jest zawarta w aplikacji / usłudze, czy też są to metody na rzeczywistych obiektach biznesowych?
JonWillis,
1

Wzrost liczby projektów wiąże się z włączeniem testowania jednostkowego i uproszczeniem wykresu zależności do tego stopnia, że ​​rzeczy nie są tak złożone, że zmiany w jednej części aplikacji psują rzeczy w pozornie niezwiązanych częściach aplikacji.

Działa to, gdy robię coś w rodzaju inwersji zależności, aby umieścić wszystkie „kontrakty”, interfejsy, klasy abstrakcyjne, obiekty przesyłania danych w jednym zestawie. W innym zestawie umieściłem wszystko, co mówi do bazy danych. Testy jednostkowe uzyskują własny montaż. Jeśli interfejs użytkownika jest zasadniczo nie do przetestowania (np. Formularze Win.NET ASP.NET), znaczną zaletą jest podzielenie interfejsu użytkownika na kod testowalny i kod niesprawdzalny - każdy zestaw. Czasami zaczyna się pojawiać jakiś kod, który nie ma nic wspólnego z bazą danych, interfejsem użytkownika lub czymkolwiek, o czym do tej pory wspominałem - to kod, który chciałbym, żeby był w środowisku .NET. Ten kod wstawię do zestawu narzędzi, a przynajmniej wstawię go do dowolnego zestawu głównego (prawdopodobnie tego z interfejsami.

Jeśli wszystkie zespoły odnoszą się do wszystkich zespołów lub prawie tak, powinny one zostać scalone z powrotem w jeden zespół. Jeśli Ty lub członkowie Twojego zespołu brakuje dyscypliny, aby nie umieszczać kodu warstwy danych w interfejsie użytkownika i interfejsu użytkownika w warstwie danych, uprość wszystko, scalając wszystko z powrotem w jedną warstwę.

Niektóre edycje Visual Studio mają problemy z wydajnością w około 15 złożeniach, czasem zależy to od rodzaju projektu. Czasami jednak może pomóc strategiczne rozładowanie plików projektu.

MatthewMartin
źródło
Obecnie jestem jedynym programistą w firmie. A także świeżo po studiach, więc jak najszybciej zaszczepić dobre praktyki w większych projektach. Jestem zainteresowany jego utrzymaniem, ponieważ specyfikacja systemu zmieniła się tak bardzo, zanim nawet zacząłem ją dokumentować, wbrew prośbom o jak najszybszy dostęp do systemu. Czy Twoim zdaniem, właściwym rozwiązaniem byłoby posiadanie zestawu zawierającego tylko interfejsy? W ten sposób zależność powinna polegać wyłącznie na interfejsach i klasach fabrycznych.
JonWillis,
1
Tak. Lepiej zrozumieć motywację podziału zgromadzeń, ale jeśli ty (lub członkowie twojego zespołu) tego nie rozumiesz, to nadal jest to tani manewr. Więc nawet jeśli skończysz ze wszystkimi zespołami zależnymi od wszystkich zespołów i nie ma nadziei na testowanie jednostek, przeniesienie rzeczy, które zachowują się jak kontrakty (interfejsy, klasy abstrakcyjne) do własnego zestawu, jest krokiem we właściwym kierunku i ma kilka wad.
MatthewMartin
-2

Jedynym dobrym powodem do posiadania więcej niż jednego projektu jest to, że musisz udostępnić zestaw klas i plików w wielu aplikacjach.

Jeśli projekty są używane tylko przez jedną aplikację, nie powinny być tworzone w pierwszej kolejności. Zamiast tego użyj przestrzeni nazw. Zaoszczędź sobie kłopotów z cyklicznymi odniesieniami, narzutem dll i zamieszaniem projektu podczas wyszukiwania plików.

Przeczytaj ten artykuł, aby uzyskać bardziej szczegółowe wyjaśnienie, dlaczego tak jest: http://lostechies.com/chadmyers/2008/07/16/project-anti-pattern-many-projects-in-a-visual-studio- plik-rozwiązania /

I jak mówi artykuł, z radością powitałbym każdego, kto ma uzasadniony powód, aby mieć wiele projektów oprócz współużytkowania kodu w różnych aplikacjach, aby powiedzieć mi, co to jest, ponieważ wątpię, że takie istnieją.

Didier A.
źródło
Docenione zostaną kontrargumenty w sprawie przegłosowania.
Didier A.