Kontrastując wszystkich nieprzyzwoitych mówców, załóżmy prawdziwą potrzebę biznesową.
(na przykład kodem dostarczanym jest kod źródłowy, klienci pochodzą z tej samej branży, a zatem są ze sobą konkurenci, a model biznesowy obiecuje zachować tajemnicę)
Ponadto załóżmy, że Twoja firma posiada narzędzia do utrzymania wszystkich oddziałów, czyli albo siły roboczej (powiedzmy 100 programistów zaangażowanych w łączenie, zakładając 5-dniowe opóźnienie wydania; lub 10 programistów zakładających, że 50-dniowe opóźnienie wydania jest OK), lub tak niesamowite zautomatyzowane testy, że automatyczne połączenia są naprawdę testowane zarówno pod kątem specyfikacji podstawowej, jak i specyfikacji rozszerzenia w każdej branży, a zatem tylko zmiany, które nie łączą się „czysto”, wymagają interwencji człowieka. Jeśli klienci płacą nie tylko za dostosowania, ale za ich utrzymanie, może to być prawidłowy model biznesowy.
Moje (i nie-mówcy) pytanie brzmi: czy masz dedykowaną osobę odpowiedzialną za dostawę do każdego klienta? Jeśli jesteś, powiedzmy, firmą liczącą 10 000 osób, może tak być.
W niektórych przypadkach może to być obsługiwane przez architekturę wtyczek , powiedzmy, że twoim rdzeniem jest pień, wtyczki mogą być przechowywane w pniu lub gałęziach, a konfiguracja dla każdego klienta jest plikiem o unikalnej nazwie lub jest przechowywana w oddziale klienta.
Wtyczki mogą być ładowane w czasie wykonywania lub wbudowane w czasie kompilacji.
Naprawdę wiele projektów jest wykonywanych w ten sposób, nadal występuje zasadniczo ten sam problem - proste podstawowe zmiany są trywialne w integracji, zmiany konfliktu muszą zostać wycofane lub zmiany w wielu wtyczkach.
Zdarzają się przypadki, gdy wtyczki nie są wystarczająco dobre, wtedy tak wiele wewnętrznych elementów rdzenia musi zostać poprawionych, że liczba interfejsów wtyczek staje się zbyt duża, aby poradzić sobie.
Idealnie byłoby to obsługiwane przez programowanie aspektowe , w którym trunk jest kodem podstawowym, a gałęzie są aspektami (to jest dodatkowy kod i instrukcje, jak podłączyć dodatki do rdzenia)
Prosty przykład, możesz określić, że niestandardowy foo
jest uruchamiany przed rdzeniem lub po klass.foo
nim, że zastępuje go, lub że otacza go i może zmieniać dane wejściowe lub wyjściowe.
Jest na to mnóstwo bibliotek, jednak problem łączenia konfliktów nie ustępuje - czyste połączenia są obsługiwane przez AOP, a konflikty nadal wymagają interwencji człowieka.
Wreszcie, taki biznes naprawdę musi zajmować się utrzymaniem oddziału , a mianowicie, czy funkcja X specyficzna dla klienta jest tak powszechna, że przeniesienie jej do rdzenia jest tańsze, chociaż nie wszyscy klienci płacą za to?