Decorator パターン (ある核 (コア) とあるオブジェクトに, 動的な機能を追加を提供する)

[Decorator] という英単語は, [装飾者] を意味する.

このパターンは, 源となるオブジェクトに, 機能という飾り付けをどんどん被せていき, 要求にあるオブジェクトに仕立て上げていくパターンである.

また, 飾り枠と中身を同一視することでより柔軟な機能拡張方法を提供する.

役割

  1. Component (部品):
機能追加の核となるクラスで, 機能拡張するメソッドのインタフェースを定義する.
  1. ConcrenteComponent (具体的な部品):
[Component] のインタフェースを実装する. 基本となる機能を実装する.
  1. Decorator (装飾者):
[Component] を実装しているオブジェクトを保持する. [Component] のインタフェースを受流し, サブクラスに実装させる. 保持対象となるのは, [ConcreteComponent], [ ConcreteDecorator[A,B] ] になる.
  1. ConcreteDecorator[A,B] (具体的な装飾者):
[Decorator] のインタフェースを実装する.
  1. Client (依頼者):
[Decorator] パターンを適用したクラスを利用し, 処理する.

クラス図

Decorator パターンのクラス図

_images/designpattern-decorator012.gif

ソースコード

  1. Component.java
1
2
3
4
public abstract class Component{
    public abstract void method1(); // 抽象メソッド
    public abstract void method2(); // 抽象メソッド
}
  1. ConcreteComponent.java
1
2
3
4
5
6
7
8
9
public class ConcreteComponent extends Component{
    public void method1(){
	System.out.print("ConcComp-m1()");
    }

    public void method2(){
	System.out.println("ConcComp-m2()");
    }
}
  1. Decorator.java
1
2
3
4
5
6
7
public abstract class Decorator extends Component{
    protected Component component;

    public Decorator(Component component){
	this.component = component;
    }
}

4-1. ConcreteDecoratorA.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public class ConcreteDecoratorA extends Decorator{
    public ConcreteDecoratorA(Component component){
	super(component);
    }

    public void method1(){
	System.out.print("ConcDecoA-m1(){");
	component.method1();
	System.out.print("}");
    }

    public void method2(){
	System.out.println("ConcDecoA-m2(){");
	component.method2();
	System.out.println("}");
    }
}

4-2. ConcreteDecoratorB.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
public class ConcreteDecoratorB extends Decorator{
    public ConcreteDecoratorB(Component component){
	super(component);
    }

    public void method1(){
	System.out.print("ConcDecoB-m1(){");
	component.method1();
	System.out.print("}");
    }

    public void method2(){
	System.out.println("ConcDecoB-m2(){");
	component.method2();
	System.out.println("}");
    }
}
  1. Client.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
public class Client{
    public static void main(String[] args){
	Component co = new ConcreteComponent();
	co.method1();
	System.out.print("\n\n");
	co.method2();
	System.out.print("\n");

	Component coA = new ConcreteDecoratorA(co);
	coA.method1();
	System.out.print("\n\n");
	coA.method2();
	System.out.print("\n");

	Component coB = new ConcreteDecoratorB(coA);
	coB.method1();
	System.out.print("\n\n");
	coB.method2();
    }
}

上記のプログラムの実行結果:

[wtopia Decorator]$ java Client
ConcComp-m1()

ConcComp-m2()

ConcDecoA-m1(){ConcComp-m1()}

ConcDecoA-m2(){
ConcComp-m2()
}

ConcDecoB-m1(){ConcDecoA-m1(){ConcComp-m1()}}

ConcDecoB-m2(){
ConcDecoA-m2(){
ConcComp-m2()
}
}