In contrasto con tutti i mendicanti, assumiamo le reali esigenze di business.
(ad esempio, il deliverable è il codice sorgente, i clienti provengono dalla stessa linea di business e quindi i concorrenti l'uno dall'altro, e il modello di business promette di mantenere segreti i propri segreti)
Inoltre, supponiamo che la tua azienda abbia gli strumenti per mantenere tutti i rami, ovvero sia manodopera (diciamo 100 sviluppatori dedicata alla fusione, supponendo un ritardo di rilascio di 5 giorni o 10 sviluppatori che assumono Intervallo di rilascio di 50 giorni è OK), o test automatici così straordinari che le unioni automatizzate sono veramente testate sia per specifiche core che per specifiche estensione in ogni ramo, e quindi solo le modifiche che non si fondono in modo "pulito" richiedono l'intervento umano. Se i tuoi clienti pagano non solo per le personalizzazioni ma per la loro manutenzione, questo potrebbe essere un modello di business valido.
La mia domanda (e nay-sayers) è, hai una persona dedicata responsabile della consegna a ciascun cliente? Se sei, per esempio, un'azienda di 10.000 persone, potrebbe essere il caso.
Questo potrebbe essere gestito da architettura dei plugin in alcuni casi, diciamo che il tuo core è trunk, i plugin possono essere tenuti in trunk o rami e la configurazione per ogni cliente è un file con un nome univoco o è tenuto nella filiale del cliente.
I plugin possono essere caricati in fase di esecuzione o integrati in fase di compilazione.
Molti progetti sono fatti in questo modo, fondamentalmente lo stesso problema si applica ancora: semplici cambiamenti di base sono banali da integrare, i cambiamenti di conflitto devono essere risolti o le modifiche sono necessarie per molti plugin.
Ci sono casi in cui i plug-in non sono abbastanza buoni, questo è il momento in cui molti interni del core devono essere ottimizzati affinché il numero di interfacce del plugin diventi troppo grande da gestire.
Idealmente questo sarebbe gestito da programmazione orientata all'aspetto , dove trunk è il codice principale, e le ramificazioni sono aspetti (cioè codice extra e istruzioni su come connettere gli extra al core)
Un semplice esempio, puoi specificare che foo
personalizzato viene eseguito prima o dopo core klass.foo
o che lo sostituisce, oppure che lo avvolge e può cambiare input o output.
Ci sono un sacco di librerie per questo, tuttavia il problema dei conflitti di unione non scompare: le unzioni pulite vengono gestite da AOP e i conflitti richiedono ancora l'intervento umano.
Finalmente questo tipo di attività deve preoccuparsi della manutenzione delle filiali , ovvero della caratteristica X specifica del cliente, così comune che è più economico spostarla verso il core, anche se non tutti i clienti lo pagano ?