この質問では、Decoratorパターンを使用して、大きなクラスのオブジェクトにほとんど機能を追加しないようにしています。
古典的なDecoratorパターンに従って、次のクラス構造を検討してください:
たとえば、これがゲーム内で発生するとします。のインスタンスは、「ラッピング」しているConcreteCharacterDecorator
機能に小さな機能を追加するためConcreteCharacter
のものです。
たとえば、キャラクターが敵に与えるダメージを表す値をmethodA()
返しますint
。ConcreteCharacterDecorator
単純にこの値に追加されます。したがって、必要なのはコードをに追加することだけmethodA()
です。の機能はmethodB()
変わりません。
ConcreteCharacterDecorator
このようになります:
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.
}
}
これは、2つのメソッドを含む小さなクラスでは問題ありません。
しかし、AbstractCharacter
15のメソッドを定義するとどうなるでしょうか。 ConcreteCharacterDecorator
少しの機能を追加することだけを目的としていますが、すべてを実装する必要があります。
少し機能を追加する1つのメソッドと、単純に内部オブジェクトに委譲する別の14のメソッドを含むクラスになります。
次のようになります。
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.
}
}
明らかに、非常に醜い。
私はおそらく、デコレータでこの問題に遭遇する最初ではありません。どうすればこれを回避できますか?
AbstractCharacterDelegator
「通常」で作成することをお勧めします(Javaのすべての「通常」メソッドはデフォルトで仮想であるため、サブクラスを継承することでオーバーライドできるため)。そして、それらの実装は単に内部オブジェクトに委任されています-そしてそれを変更したい場合は、単にそれらをオーバーライドしますか?