Esta pregunta se refiere al uso del patrón Decorator para agregar poca funcionalidad a los objetos de clases grandes.
Siguiendo el patrón clásico de Decorator, considere la siguiente estructura de clase:
Por ejemplo, imagina que esto sucede dentro de un juego. Las instancias de ConcreteCharacterDecorator
están destinadas a agregar poca funcionalidad a la ConcreteCharacter
que están 'envolviendo'.
Por ejemplo, methodA()
devuelve un int
valor que representa el daño que el personaje inflige a los enemigos. El ConcreteCharacterDecorator
simplemente agrega a este valor. Por lo tanto, solo necesita agregar código methodA()
. La funcionalidad de methodB()
permanece igual.
ConcreteCharacterDecorator
se verá así:
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.
}
}
Esto no es problema con clases pequeñas que contienen dos métodos.
¿Pero qué AbstractCharacter
pasa si se definen 15 métodos? ConcreteCharacterDecorator
tendría que implementarlos todos, a pesar de que solo está destinado a agregar poca funcionalidad.
Terminaré con una clase que contiene un método que agrega un poco de funcionalidad y otros 14 métodos que simplemente delegan en el objeto interno.
Se vería así:
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.
}
}
Obviamente, muy feo.
Probablemente no soy el primero en encontrar este problema con el Decorador. ¿Cómo puedo evitar esto?
AbstractCharacterDelegator
'regulares' (ya que todos los métodos 'regulares' en Java son virtuales de forma predeterminada, lo que significa que pueden anularse heredando subclases)? ¿Y su implementación simplemente delega en el objeto interno, y si quiero cambiar eso, simplemente anularlos?