記事のディレクトリ
ステートメント:
このブログは、「Javaデザインパターン」を勉強した後の私のメモです。レビューとレビューを容易にすることを目的としており、商用目的ではありません。
このブログはソースを示しています。侵害がある場合は、すぐに通知して削除してください。
1.デコレータモードの説明
- 定義:元のオブジェクトを変更しないことに基づいて、関数をオブジェクトにアタッチします。
- 継承よりも柔軟な代替手段を提供します(元のオブジェクト関数を拡張します)
- タイプ:構造
- クラスの機能を拡張するか、クラスに責任を追加します
- オブジェクトに関数を動的に追加します。これらの関数は動的に元に戻すことができます
- 利点
- 継承よりも柔軟な継承の強力な補足であり、元のオブジェクトを変更せずにオブジェクトに関数を拡張できます。
- さまざまな装飾と、これらの装飾の順列と組み合わせを使用することで、さまざまな効果を実現できます。
- 開閉の原則を遵守する
- 不利益
- より多くのコード、より多くのクラス、そしてより複雑なプログラムがあります
- 多層装飾の場合、動的装飾はより複雑になります
- 関連するデザインパターン
- デコレータモードとプロキシモード
- デコレータモードは、オブジェクトにメソッドを動的に追加することに重点を置いています
- プロキシモードはオブジェクトへのアクセスの制御に重点を置いており、プロキシクラスはオブジェクトに関する特定の情報をクライアントから隠すことができます
- 通常、プロキシモードを使用する場合は、プロキシクラスにクラスのインスタンスを作成することが多く、デコレータモードを使用する場合は、通常、元のオブジェクトをパラメータとしてデコレータのコンストラクタに渡します。
- デコレータパターンとアダプタパターン
- デコレータモードとアダプタモードの両方をパッケージングモードと呼ぶことができます
- デコレータとデコレートは同じインターフェイスを実装できます。または、デコレータはデコレートのサブクラスです。
- アダプターと適応クラスのインターフェースは異なります
- デコレータモードとプロキシモード
2.デコレータモードコーディング
次に、パンケーキを販売するビジネスシナリオをシミュレートします。
-
パンケーキクラスを作成する
public class Battercake { protected String getDesc() { return "煎饼"; } protected int cost() { return 8; } }
-
卵でパンケーキを作る
public class BattercakeWithEgg extends Battercake { @Override public String getDesc() { return super.getDesc()+"加一个鸡蛋"; } @Override public int cost() { return super.cost()+1; } }
-
卵とソーセージでパンケーキを作る
public class BattercakeWithEggSausage extends BattercakeWithEgg{ @Override public String getDesc() { return super.getDesc()+"加一个香肠"; } @Override public int cost() { return super.cost()+2; } }
-
テストクラス
public class Test { public static void main(String[]args){ Battercake battercake = new Battercake(); System.out.println(battercake.getDesc()+"销售价格:"+battercake.cost()); BattercakeWithEgg battercakeWithEgg = new BattercakeWithEgg(); System.out.println(battercakeWithEgg.getDesc()+"销售价格:"+battercakeWithEgg.cost()); BattercakeWithEggSausage battercakeWithEggSausage = new BattercakeWithEggSausage(); System.out.println(battercakeWithEggSausage.getDesc()+"销售价格:"+battercakeWithEggSausage.cost()); } }
演算結果:
煎饼销售价格:8 煎饼加一个鸡蛋销售价格:9 煎饼加一个鸡蛋加一个香肠销售价格:11
誰かが2つの卵を追加したい場合は、パンケーキと2つの卵クラスを作成する必要がありますが、これは継承による拡張性が非常に低くなっています。
以下では、デコレータパターンを使用します。
-
抽象パンケーキクラスを作成する
public abstract class ABattercake { protected abstract String getDesc(); protected abstract int cost(); }
-
パンケーキクラスを作成し、抽象jianbingクラスから継承します
public class Battercate extends ABattercake { @Override protected String getDesc() { return "煎饼"; } @Override protected int cost() { return 8; } }
-
抽象エンティティを継承する抽象デコレータクラスを作成する
public class AbstractDecorator extends ABattercake{ private ABattercake aBattercake; public AbstractDecorator(ABattercake aBattercake) { this.aBattercake = aBattercake; } @Override protected String getDesc() { return aBattercake.getDesc(); } @Override protected int cost() { return aBattercake.cost(); } }
-
抽象装飾クラスから受け継いだ卵入りパンケーキの装飾クラス
public class EggDecorator extends AbstractDecorator { public EggDecorator(ABattercake aBattercake) { super(aBattercake); } @Override protected String getDesc() { return super.getDesc() + "加一个鸡蛋"; } @Override protected int cost() { return super.cost() + 1; } }
-
ソーセージのパンケーキの装飾クラスは、抽象的な装飾クラスから継承されます
public class SausageDecorator extends AbstractDecorator { public SausageDecorator(ABattercake aBattercake) { super(aBattercake); } @Override protected String getDesc() { return super.getDesc() + "加一根香肠"; } @Override protected int cost() { return super.cost() + 2; } }
-
テストカテゴリでは、卵2個とソーセージ1個のパンケーキ
public class Test { public static void main(String[] args) { ABattercake aBattercake = new Battercate(); aBattercake = new EggDecorator(aBattercake); aBattercake = new EggDecorator(aBattercake); aBattercake = new SausageDecorator(aBattercake); System.out.println(aBattercake.getDesc() + " 价格:"+aBattercake.cost()); } }
演算結果:
煎饼加一个鸡蛋加一个鸡蛋加一根香肠 价格:12
クラス図は次のようになります。