Kilka dni temu dyskutowałem z kolegą na temat tego czy całość/większość kodu powinna być umieszczona w jednym dużym projekcie (jak On uważa) czy rozłożona pomiędzy mniejsze projekty (jak uważam Ja). Przez projekt rozumiem tutaj jednostkę organizacji kodu np.: csproj w Visual Studio. Duży projekt to dla mnie taki, który zawiera wszystko czyli: implementację GUI, logikę biznesową, interfejsy, struktury danych, klasy dostępu do danych itd. Może się to przekładać na liczbę linii kodu ale nie musi. Dalej, aby odróżnić projekt jako jednostkę organizacji kodu od projektu jako przedsięwzięcia biznesowego będę używał sformułowania projekt biznesowy dla tego drugiego.
Wracając do wspomnianej dyskusji to zakończyła się impasem ponieważ żaden z nas nie zmienił swojego zdania. Spowodowała jednak, że postanowiłem jeszcze raz gruntownie przemyśleć sprawę. W ten sposób powstała poniższa lista zalet i potencjalnych wad małych projektów. Listy te są skonstruowałem w ten sposób, że na początki znajdują się najważniejsze/najpoważniejsze zalety i wady.
Zalety
Reasumując jestem przekonany, że zalety dzielenia kodu na małe projekty przeważają potencjalne wady. Co więcej uważam, że problemy z małymi projektami wynikają głównie ze złego podejścia i przyjęcia nieodpowiednich rozwiązań takich jak: budowanie wszystkich projektów zamiast kilku wybranych lub z dogmatycznego trzymania się małych projektów czyli bezrefleksyjnego tworzenia małego projektu na wszystko co się da. Co za dużo to jednak nie zdrowo :)
Na koniec jedna uwaga. Na początku projektu biznesowego może się wydawać, że lepiej trzymać wszystko w dużym projekcie bo tak prościej, bo kodu mało. Ale o ile nie jest to rzeczywiście malutki projekt biznesowy to szybko okaże się, że podzielenie kodu na mniejsze projekty będzie wymagać tyle pracy, że nikomu nie będzie się tego chciało zrobić.
Wracając do wspomnianej dyskusji to zakończyła się impasem ponieważ żaden z nas nie zmienił swojego zdania. Spowodowała jednak, że postanowiłem jeszcze raz gruntownie przemyśleć sprawę. W ten sposób powstała poniższa lista zalet i potencjalnych wad małych projektów. Listy te są skonstruowałem w ten sposób, że na początki znajdują się najważniejsze/najpoważniejsze zalety i wady.
Zalety
- Łatwiejsze użycie tego samego kodu w innym projekcie biznesowym. Przy dużych projekcie również jest to możliwe ale oznacza dodanie referencji do wielu innych niepotrzebnych w danym kontekście rzeczy czyl bałagan.
- Wymusza poprawną architekturę. Na przykład jeśli GUI, logika biznesowa i dostęp do bazy danych znajdują się w innych projektach to projekt z GUI będzie miał referencję na projekt z logiką biznesową ale nie na odwrót ponieważ referencje cykliczne nie są dozwolone.
- Ułatwia dalszy rozwój. Wyobraźmy sobie sytuację, w której projekt biznesowy jest na etapie stabilizacji i zbliża się termin oddania. Z drugiej strony istnieje konieczność dalszego rozwijania jakiejś jego części. Po wdrożeniu klient zapewne będzie zgłaszał błędy. Po jakimś czasie może pojawić się potrzeba złączenia (merge) dwóch (lub więcej) ścieżek rozwoju czyli przeniesienia poprawek błędów z wersji produkcyjnej na rozwojową i dodanie nowych funkcji z wersji rozwojowej do wersji produkcyjnej. W przypadku małych projektów łatwiej zorientować się co się zmieniło, co trzeba przenieść, a co nie, czy merge spowoduje jakieś błędy itd.
- Aspekty psychologiczne. Nie przytłacza liczbą plików i folderów. Łatwiej zorientować się "o co biega" - łatwiej jest pracować z małym projektem odpowiedzialnym za jedną konkretna rzecz niż z dużym odpowiedzialnym za dziesiątki różnych rzeczy.
- Łatwiejsze utrzymanie testów jednostkowych. W przypadku podejścia, w którym testy jednostkowe są umieszczane w innym projekcie niż testowany kod będzie mieli kilka małych projektów z testami jednostkowymi. W podejściu przeciwstawnym w danym projekcie będziemy mieli ograniczoną liczbę testów dotyczących tego jednego projektu. Należy to przeciwstawić dużym projektom gdzie powstanie nam albo kolejny duży projekt na testy jednostkowe albo bardzo duży projekt zawierający wszystko plus jeszcze testy jednostkowe tego wszystkiego.
- Prostsze i łatwiejsze w utrzymaniu pliki konfiguracyjne. Ma to znaczenie jeśli używamy technologii wymagających wielu plików konfiguracyjnych, najczęsciej dokumentów XML np.: Spring.
- Krótsza kompilacja. Jeśli nie zmieniły się interfejsy to można skompilować pojedynczy, mały projekt.
- Wykonywanie brancha małego projektu trwa szybciej
- Defragmentacja pamięci. Pisałem o tym już wcześniej. Problem polega na tym, że przy ładowaniu do pamięci moduły nie są ustawiane jeden po drugim ale są umieszczane w "losowo" wybranych miejscach co powoduje poszatkowanie pamięci. W większości wypadków nie jest to problemem ale na przykład przy alokacji dużej bitmapy potrzebny jest ciągły obszar pamięci. W wyniku defragmentacji system będzie dysponował dostatecznie dużą ilością pamięci ale nie w jednym kawałku. Problem nie występuje na systemach 64-bitowych, które są coraz powszechniejsze.
- Dłuższe uruchamianie VS. Jeśli utworzymy Solution i dodamy do niego kilkadziesiąt projektów to jego otwieranie będzie trwać długo. Z drugiej strony czy aby na pewno praca z kilkudziesięcioma projektami ma sens?
- Konieczność zarządzania dużą liczbą referencji. Każdy lub prawie każdy projekt będzie miał kilka lub więcej referencji do innych projektów. Zgadzam się, że może to być problem. Z drugiej strony pracowałem przy rozwijaniu naprawdę dużego systemu składającego się z kilkunastu podsystemów, każdy z kilkunastoma małymi projektami z czego część była współdzielona i radziliśmy sobie.
- Trudniejsza instalacja. Wynika to z dużej ilości bibliotek dll, które powstają w wyniku kompilacji wielu małych projektów. Mogą również wystąpić konflikty wersji. Podobnie jak wyżej zgadzam się, że jest to możliwe ale podobnie jak wyżej przeciwstawiam tej wadzie swoje doświadczenie, które mówi co innego.
- Dłuższa kompilacja całego systemu. Zgadzam się, przy wielu małych projektach kompilacja wydłuży się i to znacznie. Jednak i tutaj dołożę swoje trzy grosze. Jak często istnieje potrzeba przekompilowania całego systemu? Jeśli w danym momencie pracujemy z kilkoma konkretnymi projektami to po co wykonywać build wszystkich pozostałych? Ma to sens, jeśli zostały zmienione klasa, struktury lub interfejsy używane w wielu innych projektach.
- Problemy z konfiguracją tych samych rzeczy w różnych projektach. Przy odpowiedniej architekturze systemu i zastosowaniu odpowiednich wzorców projektowych (singleton, fabryka) nie jest to dla mnie żaden problem.
- Zwiększony czas uruchamiania aplikacji. Tak ale o ułamki sekund.
Reasumując jestem przekonany, że zalety dzielenia kodu na małe projekty przeważają potencjalne wady. Co więcej uważam, że problemy z małymi projektami wynikają głównie ze złego podejścia i przyjęcia nieodpowiednich rozwiązań takich jak: budowanie wszystkich projektów zamiast kilku wybranych lub z dogmatycznego trzymania się małych projektów czyli bezrefleksyjnego tworzenia małego projektu na wszystko co się da. Co za dużo to jednak nie zdrowo :)
Na koniec jedna uwaga. Na początku projektu biznesowego może się wydawać, że lepiej trzymać wszystko w dużym projekcie bo tak prościej, bo kodu mało. Ale o ile nie jest to rzeczywiście malutki projekt biznesowy to szybko okaże się, że podzielenie kodu na mniejsze projekty będzie wymagać tyle pracy, że nikomu nie będzie się tego chciało zrobić.