Kilka klientów na jednym kodzie - jak to rozwiązać?

0

Opis problemu:
Klienci: A, B, C
Branche w repo: główny, branch_a, branch_b, branch_c

Aktualnie to wygląda w ten sposób, że jest jeden główny branch plus branch A, B i C. Branch główny to taka trochę klasa abstrakcyjna, bo wchodzi tam wszystko co ma wejść na instancje A, B oraz C. W momencie aktualizacji główny branch jest domergowywany do pozostałych. Zmiany, które są tylko dla klienta A wchodzą tylko na branch_a itd.

Jakie rozwiązania widzę:
Rozwiązanie, które jest w zgodzie z myśleniem Janusza, czyli zostawiamy kod dalej na tym samym repo (a nie robimy oddzielnie dla każdego klienta) spowoduje jedno z dwóch:
a) Pierdyliard ifów w kodzie (teraz dwa, a w przyszłości dwa tysiące)
b) Można wczytywanie odpowiednich widoków zamieść głęboko pod dywan, żeby uniknąć ifów i sprawdać klienta tylko raz podczas bootstrapa aplikacji, ale wtedy dla każdej z instancji musiałby być tworzony osobny widok, bo przecież wszystko stoi na jednym kodzie - FUCK DRY.

Pomijam fakt związany np. z optymalizacją zapytań, bo jeżeli jeden klient będzie chciał widzieć 2 kolumny, a drugi 20 to tak czy siak będzie tam trzeba albo załatować wszystkie potrzebne dane, albo kolejne ify?

Mi się osobiście wydaje, że rozdzielenie tego, tak żeby każdy klient miał swój osobny kod (a nie wszystko razem) jest najbardziej sensowne, ale moje doświadczenie jest zbyt małe, żeby to stwierdzić.

Co myślicie?

3

ja mysle, ze mozna to rozwizac inaczej. To rozwiazanie ktore macie juz wlasnie wam sprawia problemy (osobne repo pod klienta a pozniej mergowanie do kilku branchy tej samej funkcjonalnosci...)

Kod wspolny dla wszystkich klientow. Dokladnie taki sam.
Dodac osobny plik dla klienta (jakis plik konfiguracyjny). Jak zabezpieczyc to pomijam (bo to nie o tym). Przy starcie aplikacji (ktora niech posiada wszystkie feature. Nawet te ktore chce tylko klient A... bo przeciez chyba nie szkoda Wam miejsca na dysku?) niech czyta z pliku konfiguracyjnego co ma wlaczyc a co ma wylaczyc (w sensie co ma zainicjalizowac jako nowy obiekt).

Takie rozwiazanie nie jest idealne, ale na pewno lepsze od tego co bedziecie miec teraz. Co trzeba zrobic to

  • Dokumentowac co sluzy do czego przy parsowaniu pliku
  • Jeden feature -> Jedna klasa (jakas abstrakcyjna glowna).
  • Jakis Container na abstrakcyjne klasy ktore sa jakims featurem.

Do tego mozna napisac jakis prosty tool ktory generuje taki plik. Wiec jak bedzie kolejny klient to sobie bedziecie mogli wlaczyc/wylaczyc co tylko chcecie.

Wada tego rozwiazania jest utrzymywanie tych plikow konfiguracyjnych. Jezeli w firmie zabraniknie kogos kto ogarnia ten temat i nie bedzie dokumentacji to bedzie to dosc ciezkie do utrzymania (ale to mozna zwiekszyc za pomoca unit testow, integracyjnych testow etc)

Ale takie rozwiazanie zapewne wymaga u Was przebudowania calego kodu... wiec zapewne nie wchodzi w gre ;) Jezeli tak jest to daj znac. Pomysli sie nad czyms innym

2

@Desu ja bym jednak szedł jeszcze głębiej w generalizacje tego kodu zamiast w zrobienie kilku osobnych codebasów. Dlaczego:

  1. Kilka codebasów = problem kiedy chcesz wprowadzić fixy we wszystkich wersjach
  2. Problem kiedy nagle jeden klient będzie chciał coś co ma juz drugi klient. Będziesz musiał sie bawić w ekstrakcje i mergowanie
  3. To co wyżej ale lvl hard -> nowy klient który chce po trochu z funkcji które maja inni klienci = powodzenia z ekstrakcją i składaniem tego :D

Dużo lepiej i wygodniej jest zrobić jedne generalny codebase ze wszystkimi opcjami i dać możliwość włączenia lub wyłączenia ich z poziomu jakiegoś panelu konfiguracyjnego. Przy odpowiedniej architekturze można wykorzystać kontener IoC do złozenia aplikacji bez konieczności wprowadzania ifów w kodzie.

0

Dzięki Panowie za odpowiedzi. Jakoś sobie spróbuję z tym poradzić. Powiedzcie mi jeszcze jak taką sytuację się rozwiązuje wcześniej niż w momencie gdy już wszystko się wali?

Jeżeli wiem, że mam produkt, który będę sprzedawał powiedzmy 5 klientom to jak to jest rozwiązywane "po bożemu" na etapie projetowania aplikacji?

3

Jeden mocno konfigurowalny projekt (np. z jakimś key-value store albo bazą danych z parametrami konfiguracyjnymi, gdzie masz np. dialogi i labelki oraz informacje na temat konfiguracji komponentów), często z możliwością dodawania dynamicznych pluginów.
Dzieki temu klient ma swoja konfiguracje a do tego jeśli potrzebuje jakiegoś mega customowego rozwiązania to tworzy sie na to osobny plugin.

1 użytkowników online, w tym zalogowanych: 0, gości: 1