Questa domanda riguarda l'uso del pattern Decorator per aggiungere poche funzionalità agli oggetti di classi grandi.
Seguendo il classico pattern Decorator, considera la seguente struttura di classe:
Ad esempio, immagina che questo avvenga all'interno di un gioco. Le istanze di ConcreteCharacterDecorator
hanno lo scopo di aggiungere poca funzionalità al ConcreteCharacter
che sono 'wrapping'.
Ad esempio, methodA()
restituisce un valore int
che rappresenta il danno che il personaggio infligge ai nemici. ConcreteCharacterDecorator
aggiunge semplicemente a questo valore. Pertanto, è sufficiente aggiungere il codice a methodA()
. La funzionalità di methodB()
rimane la stessa.
ConcreteCharacterDecorator
sarà simile a questo:
class ConcreteCharacterDecorator extends AbstractCharacterDecorator{
ConcreteCharacter character;
public ConcreteCharacterDecorator(ConcreteCharacter character){
this.character = character;
}
public int methodA(){
return 10 + character.methodA();
}
public int methodB(){
character.methodB(); // simply delegate to the wrapped object.
}
}
Questo non è un problema con le classi piccole che contengono due metodi.
Ma cosa succede se AbstractCharacter
ha definito 15 metodi? ConcreteCharacterDecorator
dovrebbe implementarli tutti, anche se ha solo lo scopo di aggiungere poca funzionalità.
Finirò con una classe contenente un metodo che aggiunge una piccola funzionalità e altri 14 metodi che delegano semplicemente all'oggetto interno.
Sembrerebbe di sì:
class ConcreteCharacterDecorator extends AbstractCharacterDecorator{
ConcreteCharacter character;
public ConcreteCharacterDecorator(ConcreteCharacter character){
this.character = character;
}
public int methodA(){
return 10 + character.methodA();
}
public int methodB(){
character.methodB(); // simply delegate to the wrapped object.
}
public int methodC(){
character.methodC(); // simply delegate to the wrapped object.
}
public int methodD(){
character.methodD(); // simply delegate to the wrapped object.
}
public int methodE(){
character.methodE(); // simply delegate to the wrapped object.
}
public int methodF(){
character.methodF(); // simply delegate to the wrapped object.
}
public int methodG(){
character.methodG(); // simply delegate to the wrapped object.
}
public int methodH(){
character.methodH(); // simply delegate to the wrapped object.
}
public int methodI(){
character.methodI(); // simply delegate to the wrapped object.
}
public int methodJ(){
character.methodJ(); // simply delegate to the wrapped object.
}
public int methodK(){
character.methodK(); // simply delegate to the wrapped object.
}
public int methodL(){
character.methodL(); // simply delegate to the wrapped object.
}
public int methodM(){
character.methodM(); // simply delegate to the wrapped object.
}
public int methodN(){
character.methodN(); // simply delegate to the wrapped object.
}
public int methodO(){
character.methodO(); // simply delegate to the wrapped object.
}
}
Ovviamente, molto brutto.
Probabilmente non sono il primo a incontrare questo problema con Decorator. Come posso evitare questo?