❝本稿はデザインパターンシリーズの3回目で、本日は主にデコレータパターンについて学びます。
❞
そんな感じがないのかわかりません。読んで勉強すれば理解できても、しばらくすると忘れてしまうので、最初からいくつか質問をして、しばらくしてから復習しました。いくつかの質問は、学んだ知識を統合するために、これらの知識のポイントをあなたの脳に結びつけます。繰り返し考え、点を線に入れ、最後にナレッジブロックを形成し、それを消化できることを願っています。
質問して勉強する
-
デコレータモードとは何ですか? -
どのようなシナリオでデコレータモードを使用する必要がありますか? -
デコレータパターンを実装する方法は? -
共通のフレームワークまたはソースコードに反映されるのはどのような場合ですか?
デコレータパターンのコンセプト
まず、デコレータモードの説明を見てみましょう。
❝「デコレータモード」は、オブジェクトに責任を動的に付加します。機能を拡張するために、デコレーターは継承よりも柔軟な代替手段を提供します。
❞
「新しい設計原則」:クラスは、拡張のために開かれ、変更のために閉じられる必要があります。
上記の定義はデコレータパターンの「役割」を説明していますが、実装で実際に「適用」する方法は説明していません。
次に、クラス図を調べ、クラス図と組み合わせて注意深く分析します。
上のクラス図から、デコレータパターンを理解しましょう
-
デコレータと装飾されたオブジェクトは同じスーパータイプを持っています -
オブジェクト(コンポーネントの特定のコンポーネント)を1つ以上のデコレータでラップできます -
デコレータと装飾されたオブジェクトは同じスーパータイプを持っているので、装飾されたオブジェクトは、元のオブジェクト(ラップ)の代わりにいつでも使用できます -
「デコレーターは、特定の目的を達成するために、委託されたデコレーターの動作の前または後に独自の動作を追加できます。」 これは、使用方法の後半で明らかになります。 -
オブジェクトはいつでも装飾できるので、実行時にお気に入りのデコレータでオブジェクトを動的かつ無制限に装飾できます
使用するシーン
現在、モカ、カプチーノ、マキアート、カンパーナなど、さまざまな種類のコーヒーを販売できるコーヒーショップがあります。また、特定のコーヒーごとに、ミルクフロス、キャラメル、豆乳、モカなどの異なるフレーバーを追加することもできます。最終的な価格を変えるには、異なるフレーバーが必要です。このシーンがOOのアイデアを使用して設計されている場合、どうしますか?
このシーンがデコレータモードに非常に適していることは間違いありません。まず、デコレータはコーヒーの種類であり、デコレータはさまざまなスパイスです。そのため、価格を計算するときに、レイヤーごとにコミッションして最終結果を得ることができます。コーヒーを飾るためにデコレータパターンを使用しているかどうかを確認します。
上記のスターバックスコーヒーの例を見てみると、これはデコレータパターンのクラス図フレームワークに対応していますか?誰もが慎重に考えることができます。
統合および拡張
上記のデコレータパターンを使用してシーンを作成します。既存のコードを変更せずに実装できるかどうかをテストし、デザインパターンの魅力を体験してみましょう。
「ダブルモカ豆乳フォームラテを注文しますか?」
とても便利ですか?デコレータモードを使って組み合わせを広げて魅力を体験しましょう。。
実装
上記の例を組み合わせて、コードの実装を見てみましょう。
// 饮料的基础类,即component
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description; } // cost必须在子类实现 public abstract double cost(); }
調味料の抽象クラス、つまりデコレータクラス:
// 调料抽象类即装饰者类,这个类必须要能替换 Beverage,所以要继承自 Beverage 类
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
これで基本クラスができたので、次は特定の飲み物です。
// 蓝山
public class BlueMountainCoffee extends Beverage {
public BlueMountainCoffee() {
description = "BlueMountainCoffee";
}
@Override public double cost() { return 0; } } // 卡布奇诺 public class Cappuccino extends Beverage { public Cappuccino() { description = "Cappuccino"; } @Override public double cost() { return 23; } } // 意式浓缩咖啡 public class Espresso extends Beverage { public Espresso() { description = "Espresso"; } @Override public double cost() { return 25; } } // 拿铁 public class Latte extends Beverage { public Latte() { description = "Latte"; } @Override public double cost() { return .89; } }
具象コンポーネントと抽象コンポーネントができたので、デコレーターパターンクラス図を比較することで具象デコレーターを実装できます。
// 摩卡是一个装饰者,所以扩展自 CondimentDecorator
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
} @Override public String getDescription() { return beverage.getDescription() + ",Mocha"; } // 首先调用委托被装饰者对象,以计算价钱,然后再加上Mocha价钱 @Override public double cost() { return .20 + beverage.cost(); } } // 豆浆 public class Soy extends CondimentDecorator { Beverage beverage; public Soy(Beverage beverage) { this.beverage = beverage; } @Override public String getDescription() { return beverage.getDescription() + ",Soy"; } @Override public double cost() { return 2.0 + beverage.cost(); } }
次のステップは、デコレータモードの魅力を示すことです。
// 测试类
public class StarbuzzCoffee {
public static void main(String[] args) {
// 一杯Espresso,不加调料
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + "$" + beverage.cost()); // 一杯加摩卡和豆浆的蓝山咖啡 Beverage beverage1 = new BlueMountainCoffee(); beverage1 = new Mocha(beverage1); beverage1 = new Soy(beverage1); System.out.println(beverage1.getDescription() + "$" + beverage1.cost()); } }
現時点では、作成するオブジェクトはすべてハードコードされた新しいものであり、あまり友好的ではありません。フォローアップでファクトリモードを学習するので、問題ありません。引き続き学習してください。
実際のデコレーター
以下は、通常使用されるjdkのデコレータパターンの例です。
Java I / O
リストされた順序はデコレータからです->デコレート
LineNumberInputStream-> BufferedInputStream-> FileInputStream
一見すると、これは基本的に上記のデコレータパターンクラス図と同じです。JvaaI / Oパッケージのクラスをもう一度読むと、きっと「すごい」感嘆符が表示されると思います。
全文が終わりました!けんか
オリジナルにするのは簡単ではありません。少しでもお役に立てれば幸いです。この記事の内容があなたが得たものであると思われる場合は、[私が見ている]をクリックするか、転送して共有し、より多くの友達に見せてください。