Ho un progetto Java legacy con un sacco di codice. Il codice utilizza pattern MVC ed è ben strutturato e ben scritto. Ha anche un sacco di test unitari ed è ancora attivamente mantenuto (bug fixing, aggiunta di funzionalità minori). Pertanto voglio mantenere la struttura originale e lo stile del codice il più possibile.
Ho l'obiettivo di iniettare un nuovo comportamento in una classe esistente. Come un'anatra addestrata a saltare. Poi chiedo a tutte le mie anatre di saltare. Coloro che possono - saltare. Quelli che non possono fare nulla che è perfettamente OK con me.
La nuova funzione che sto per aggiungere è concettuale, quindi devo apportare le mie modifiche a tutto il codice. Per minimizzare le modifiche, ho deciso di non estendere le classi esistenti ma di usare il contenimento:
class ExistingClass
{
// .... existing code
// my code adding new functionality
private ExistingClassExtension extension = new ExistingClassExtension();
public ExistingClassExtension getExtension() {return extension;}
}
...
// somewhere in code
ExistingClass instance = new ExistingClass();
...
// when I need a new functionality
instance.getExtension().newMethod1();
Tutte le funzionalità che sto aggiungendo si trovano all'interno di una nuova classe ExistingClassExtension. In realtà sto aggiungendo solo queste 2 linee a ogni classe che deve essere estesa.
Così facendo non ho bisogno di istanziare nuove classi estese su tutto il codice e posso usare test esistenti per assicurarmi che non ci sia regressione.
Tuttavia, i miei colleghi sostengono che in questa situazione non si tratta di un approccio OOP appropriato e ho bisogno di ereditare da ExistingClass
per aggiungere una nuova funzionalità.
Che ne pensi? Sono a conoscenza di numerose domande sull'eredità / contenimento qui, ma ritengo che la mia domanda sia diversa.
EDIT: La maggior parte delle persone che rispondono alla mia domanda presumono che una relazione di contenimento sembri così:
class NewClass
{
OldClass instanceOfOldClass;
void oldFunctionality() { instanceOfOldClass.oldFunctionality();}
void newFunctionality() { // new code here }
}
Ma non è una specie di relazione di contenimento?
class OldClass
{
void OldFunctionality();
NewClass instanceOfNewClass;
void NewFunctionality {instanceOfNewClass.NewFunctionality();}
}