Diese Frage betrifft die Verwendung des Decorator-Musters, um Objekten großer Klassen wenig Funktionalität hinzuzufügen.
Beachten Sie nach dem klassischen Decorator-Muster die folgende Klassenstruktur:
Stellen Sie sich zum Beispiel vor, dies passiert innerhalb eines Spiels. Instanzen von ConcreteCharacterDecorator
sollen dem ConcreteCharacter
"Wrapping" wenig Funktionalität hinzufügen .
Gibt beispielsweise methodA()
einen int
Wert zurück, der den Schaden darstellt, den der Charakter Feinden zufügt. Das ConcreteCharacterDecorator
erhöht einfach diesen Wert. Daher muss nur Code hinzugefügt werden methodA()
. Die Funktionalität von methodB()
bleibt gleich.
ConcreteCharacterDecorator
wird so aussehen:
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.
}
}
Dies ist kein Problem bei kleinen Klassen mit zwei Methoden.
Aber was ist, wenn AbstractCharacter
15 Methoden definiert sind? ConcreteCharacterDecorator
müsste sie alle implementieren, obwohl es nur dazu gedacht ist, wenig Funktionalität hinzuzufügen.
Am Ende werde ich eine Klasse haben, die eine Methode enthält, die ein wenig Funktionalität hinzufügt, und weitere 14 Methoden, die einfach an das innere Objekt delegieren.
Es würde so aussehen:
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.
}
}
Offensichtlich sehr hässlich.
Ich bin wahrscheinlich nicht der erste, der dieses Problem mit dem Dekorateur hat. Wie kann ich das vermeiden?
AbstractCharacterDelegator
"regulär" zu setzen (da alle "regulären" Methoden in Java standardmäßig virtuell sind - was bedeutet, dass sie durch das Erben von Unterklassen überschrieben werden können)? Und lassen Sie ihre Implementierung einfach an das innere Objekt delegieren - und wenn ich das ändern möchte, überschreiben Sie sie einfach?