動的に表現するために使用するデザインパターンです。
動的接続の意味は、機能を付加する時、
動的接続の意味は、機能を付加する時、
特定の方法や、手順に従って接続されないことを意味します。
車を作り過程を想像して考えてください。
工程中、ナビゲーション取り付け、スキンチューニングし、サンルーフの付着を順番にする必要はありません。ご客のご要望に合わせて制作するはずです。
車を作り過程を想像して考えてください。
工程中、ナビゲーション取り付け、スキンチューニングし、サンルーフの付着を順番にする必要はありません。ご客のご要望に合わせて制作するはずです。
下のコードをご覧ください。
public interface Car {
public void assemble();
}
public class BasicCar implements Car {
@Override
public void assemble() {
System.out.print("Basic Car.");
}
}
public class CarDecorator implements Car {
protected Car car;
public CarDecorator(Car c){
this.car=c;
}
@Override
public void assemble() {
this.car.assemble();
}
}
public class LuxuryCar extends CarDecorator {
public LuxuryCar(Car c) {
super(c);
}
@Override
public void assemble(){
super.assemble();
System.out.print(" Adding features of Luxury Car.");
}
}
public class SportsCar extends CarDecorator {
public SportsCar(Car c) {
super(c);
}
@Override
public void assemble(){
super.assemble();
System.out.print(" Adding features of Sports Car.");
}
}
そして、そのインタフェースを実装したBasicCarクラスがあります。
ところで車を少しチューニングしたくなりました。
派手な(Luxury)車とスポーツ(Sports)車にしようと思います。
CarDecoratorを使い車を二つの外見に飾りしようとします。
このCarDecoratorが飾りできる車はCarであれば、どんな車か気にしません。
なのでSportCarとLuxuryCarの部品を提供してくれるクラス2つを作成しました。
SportsCarとLuxuryCarは厳密に車ではありません。部品を提供してくれるクラスです。
この部品を使い車をチューニングできます。
public class CarTest {
public static void main(String[] args) {
Car sportsCar = new SportsCar(new BasicCar());
sportsCar.assemble();
System.out.println("\n*****");
Car sportsLuxuryCar = new LuxuryCar(new SportsCar(new BasicCar()));
sportsLuxuryCar.assemble();
System.out.println("\n*****");
// 以下はしちゃいけないコードです。
Car car = new LuxuryCar(new SportsCar());
Car car2 = new SportsCar(new LuxuryCar());
}
}
最初のラインは基本車を飾るスポーツ車です。
この車は基本車+スポーツ車の部品を使用して、スポーツ車の属性を持ちます。
下には基本車+スポーツ車の部品+派手な車の部品を持って派手なスポーツ車を作りました。
以上のようにオブジェクトを飾るデザインパターンをデコレーションパターンと呼びます。
このパターンは、オブジェクトの装飾をかなり柔軟に処理することができます。
覚えておくべき点は二つです。
1.デコレーションは順番に関係なく使えます。
2.飾る属性を持つ基本的なオブジェクトが必ず必要です。
2.飾る属性を持つ基本的なオブジェクトが必ず必要です。
すなわち、サンプルコードではSportsCarをLuxuryCarで包んだ形にしましたが
new SportsCar(new LuxuryCar(new BasicCar()));
こうして逆にしても関係がありません。
最後に包んだからって内側にあるオブジェクトに依存するわけではありません。
ただ、基本的なオブジェクトのみ他のオブジェクトが依存した形を持ちます。
なので、最後に見てわかるとおり、
デフォルトのオブジェクトを使っていないコードは、コンパイルエラーが出ます。
写真及びコードの源
댓글 없음:
댓글 쓰기