Pracuję nad dużym projektem oprogramowania, który jest wysoce dostosowany do potrzeb różnych klientów na całym świecie. Oznacza to, że mamy może 80% kodu, który jest wspólny dla różnych klientów, ale także dużo kodu, który musi się zmieniać z jednego klienta na drugiego. W przeszłości zajmowaliśmy się tworzeniem oddzielnych repozytoriów (SVN), a kiedy rozpoczął się nowy projekt (mamy niewielu, ale dużych klientów), utworzyliśmy kolejne repozytorium w oparciu o wcześniejszy projekt, który ma najlepszą bazę kodu dla naszych potrzeb. To działało w przeszłości, ale mieliśmy kilka problemów:
- Błędy naprawione w jednym repozytorium nie są załatane w innych repozytoriach. Może to być problem z organizacją, ale trudno mi naprawić i załatać błąd w 5 różnych repozytoriach, pamiętając, że zespół utrzymujący to repozytorium może znajdować się w innej części świata i nie mamy ich środowiska testowego , nie znają harmonogramu ani wymagań, jakie mają („błąd” w jednym kraju może być „cechą” w innym).
- Funkcje i ulepszenia wprowadzone dla jednego projektu, które mogą być również przydatne w innym projekcie, są tracone lub jeśli są używane w innym projekcie, często powodują duże problemy z łączeniem ich z jednej bazy kodu do drugiej (ponieważ obie gałęzie mogły być rozwijane niezależnie przez rok ).
- Refaktoryzacje i ulepszenia kodu dokonane w jednej gałęzi programistycznej zostają utracone lub powodują więcej szkody niż pożytku, jeśli trzeba scalić wszystkie te zmiany między gałęziami.
Dyskutujemy teraz, jak rozwiązać te problemy i do tej pory wymyśliliśmy następujące pomysły, jak to rozwiązać:
Utrzymuj rozwój w oddzielnych gałęziach, ale lepiej organizuj się, mając centralne repozytorium, w którym ogólne poprawki błędów są łączone, a wszystkie projekty scalają zmiany z tego centralnego repozytorium do swoich własnych regularnie (np. Codziennie). Wymaga to dużej dyscypliny i dużego wysiłku w celu połączenia oddziałów. Nie jestem więc przekonany, że to zadziała i możemy zachować tę dyscyplinę, zwłaszcza gdy pojawia się presja czasu.
Porzuć oddzielne gałęzie programistyczne i posiadaj centralne repozytorium kodu, w którym żyje cały nasz kod, i dostosowuj go, mając moduły wtykowe i opcje konfiguracji. Używamy już kontenerów wstrzykiwania zależności do rozwiązywania zależności w naszym kodzie i postępujemy zgodnie ze wzorcem MVVM w większości naszego kodu, aby w czysty sposób oddzielić logikę biznesową od naszego interfejsu użytkownika.
Drugie podejście wydaje się być bardziej eleganckie, ale mamy wiele nierozwiązanych problemów w tym podejściu. Na przykład: jak obsługiwać zmiany / uzupełnienia w modelu / bazie danych. Używamy .NET z Entity Framework, aby mieć silnie typowane podmioty. Nie rozumiem, w jaki sposób możemy obsłużyć właściwości wymagane dla jednego klienta, ale bezużyteczne dla innego klienta bez zaśmiecania naszego modelu danych. Myślimy o rozwiązaniu tego w bazie danych za pomocą tabel satelitarnych (posiadających osobne tabele, w których nasze dodatkowe kolumny dla konkretnego obiektu żyją z odwzorowaniem 1: 1 na oryginalny obiekt), ale jest to tylko baza danych. Jak sobie z tym poradzić w kodzie? Nasz model danych znajduje się w centralnej bibliotece, której nie bylibyśmy w stanie rozszerzyć dla każdego klienta stosującego to podejście.
Jestem pewien, że nie jesteśmy jedynym zespołem zmagającym się z tym problemem i jestem zszokowany, gdy znalazłem tak mało materiału na ten temat.
Więc moje pytania są następujące:
- Jakie masz doświadczenie z wysoce spersonalizowanym oprogramowaniem, jakie podejście wybrałeś i jak to zadziałało?
- Jakie podejście polecasz i dlaczego? Czy istnieje lepsze podejście?
- Czy są jakieś dobre książki lub artykuły na ten temat, które możesz polecić?
- Czy masz konkretne zalecenia dla naszego środowiska technicznego (.NET, Entity Framework, WPF, DI)?
Edytować:
Dziękuję za wszystkie sugestie. Większość pomysłów pasuje do tych, które już mieliśmy w naszym zespole, ale naprawdę pomocne jest zapoznanie się z ich doświadczeniem i wskazówkami, jak je lepiej wdrożyć.
Nadal nie jestem pewien, w którą stronę pójdziemy i nie podejmuję decyzji (sam), ale przekażę to zespołowi i jestem pewien, że będzie to pomocne.
W tej chwili tenor wydaje się być pojedynczym repozytorium wykorzystującym różne moduły specyficzne dla klienta. Nie jestem pewien, czy nasza architektura jest gotowa na to, ani ile musimy zainwestować, aby ją dopasować, więc niektóre rzeczy mogą przez jakiś czas żyć w osobnych repozytoriach, ale myślę, że to jedyne długoterminowe rozwiązanie, które zadziała.
Dziękuję raz jeszcze za wszystkie odpowiedzi!