意図
オブジェクトに機能を動的に追加します。
クラス図
デコレータとConcreteComponentはどちらもComponentを継承します。具象コンポーネントのメソッド実装は他のオブジェクトに依存する必要はなく、デコレータはコンポーネントを組み合わせて他のデコレータや具象コンポーネントを装飾できます。いわゆるデコレーションとは、デコレータをデコレートに配置することで、デコレータの機能を動的に拡張することです。デコレータのメソッドの一部はそれ自体であり、それはその関数に属し、それを実現するためにデコレートのメソッドを呼び出し、それによってデコレートの機能も保持します。ご覧のとおり、具象コンポーネントのメソッド実装のみが他のオブジェクトに依存する必要がないため、具象コンポーネントは装飾レベルの最低レベルである必要があります。
実装
さまざまな種類の飲料を設計し、ミルクを追加できるなどの材料を使用して飲料を追加でき、新しい材料の動的な追加をサポートします。材料が追加されるたびに、飲料の価格が上昇し、飲料の価格を計算する必要があります。
下の図は、新しいモカ成分がダークロースト飲料に追加され、次にホイップ成分が追加されたことを示しています。DarkRoastはモカに包まれ、モカはホイップに包まれています。これらはすべて同じ親クラスから継承し、両方にcost()メソッドがあります。外部クラスのcost()メソッドは、内部クラスのcost()メソッドを呼び出します。
public interface Beverage {
double cost();
}
public class DarkRoast implements Beverage {
@Override
public double cost() {
return 1;
}
}
public abstract class CondimentDecorator implements Beverage {
protected Beverage beverage;
}
public class Mocha extends CondimentDecorator {
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public double cost() {
return 1 + beverage.cost();
}
}
public class Whip extends CondimentDecorator {
public Whip(Beverage beverage) {
this.beverage = beverage;
}
@Override
public double cost() {
return 1 + beverage.cost();
}
}
public class Client {
public static void main(String[] args) {
Beverage beverage = new DarkRoast();
beverage = new Mocha(beverage);
beverage = new Whip(beverage);
System.out.println(beverage.cost());
}
}
3.0
注意:
1.飲料:飲料
2.調味料:調味料;調味料
設計原則
クラスは拡張のために開いて、変更のために閉じる必要があります。つまり、新しい機能が追加されたときにコードを変更する必要はありません。飲料は、飲料コードを変更することなく、動的に新しい成分を追加できます。
すべてのクラス設計がこの原則を満たすことは不可能であり、この原則は、変更が発生する可能性が最も高い場所に適用する必要があります。
JDK
- java.io.BufferedInputStream(InputStream)
- java.io.DataInputStream(InputStream)
- java.io.BufferedOutputStream(OutputStream)
- java.util.zip.ZipOutputStream(OutputStream)
- java.util.Collections#checked List | Map | Set | SortedSet | SortedMap