3 - Decoratorパターンデザインパターン

0注文

装飾パターン - >オブジェクト合成方法、実行時の装飾で。これは、新たな責任を付与するオブジェクトの基礎となるコードを変更することなく、いずれであってもよいです

例1.コーヒーショップ

問題:抽象スーパー飲料ドリンク、あまりにも多くのサブカテゴリー、クラスコンプレックスの爆発的な出現

ここに画像を挿入説明
もちろん、親クラスを継承しようとして新しい飲料の出現を維持することは困難です。

特殊なケース:ドリンク、三回ミルクの泡のコーヒーとみなさダブルミルクの泡のコーヒー、...飲み物の無限の多様性が現れました。

これは、2つの原則に違反しましたか?

  • 指向プログラミングを実現します
  • これらの変化のいくつかは、コスト()メソッドが変更されるように、引き出されていません

原則:開発-クローズド(変更はから拡張することができます)

目標:あなたは新しい動作で、既存のコードを変更せずにすることができ、簡単に拡張クラスを許可します。

OK、ここに上記飲料の承継について:クラスの爆発の数、剛性設計、維持することは困難であり、基底クラスの関数は、すべてのサブクラスには適していません。

どのように装飾模様の装飾?お客様が飾るために、本体とドリンクに使用するスパイスをセンプルモカとミルクの泡のコーヒーを想定する必要があります。

  • 深いコーヒー文化を取ることDarkRoastオブジェクト(飲料から継承)

  • 装飾品とモカモカ

  • ミルクの泡で飾らホイップ

  • 通話コスト()メソッド、手数料(代理人)に頼るべきではスパイスの価格に追加されます

    私の質問:どのように飾るために?どのように委任するには?何を委託していますか?

    私は、JDKに装飾的なパターン入力および出力ストリームだけを覚えている装飾的なパターンです。しかし、どのように達成するために?層に包まれたが、起こっていたことが実現されている。理解しやすい理解できますか?そして、私は最終的にどのようにこの装飾にコーヒーの合計価格を計算するには?

ここに画像を挿入説明
ここでの例としては、外費用のコスト結果の内部に依存しています。

もちろん**:**デコレータした後、特定の目的を達成するために、自分自身の行動で、委託対象者の前に行動して飾ることができます。 - >どのように達成するために?

同じスーパークラスでデコレーターデコレータ。 - >デコレータデコレータに、多形性置換することができます。

Decoratorパターンを定義します。2.

Decoratorパターンの動的オブジェクトに添付の責任。膨張中、継承よりも柔軟。

ここに画像を挿入説明

例えばクラス図ビューアカフェ:

ここに画像を挿入説明

明らかに:飲料がデコレータでなければなりませんよう、スパイスはデコレータを持っていました。

QUESは:指向のプログラミング・インターフェースので、なぜ飲料に設計インターフェースを入れていない、と抽象クラスとしてそれを扱いますか?

最初のプログラムから書籍の答:(答え)は、飲料は通常、Decoratorパターンは、抽象クラスを使用することで、抽象クラスで、インタフェースも使用することができます。しかし、避けるために**既存のコードを変更します。**変更後の新たな問題を作成することができ、すべての、いくつかの既存のコードの一般的な問題の後。

3.コード

この章ではよく理解し、理論的に理解されているが、それは達成することが少し難しかった前に、私が実現していなかった、それはコードを書くことです。

/**
 * 抽象基类
 */
public abstract class Beverage {
    protected String description="Unknown Beverage";//protected是子类可以访问 无 是 默认情况 同一个包下的类可以访问

    public String getDescription() {
        return description;
    }

    public abstract double cost();
}

デコレータ

/**
 * 浓缩咖啡
 */
public class Espresso   extends Beverage {

    public Espresso() {
        description="Espresso--浓缩咖啡";
    }

    @Override
    public double cost() {
        return 1.99;
    }
}
/**
 * 混合--黑咖啡
 */
public class HouseBlend extends Beverage {
    @Override
    public double cost() {
        return 0.89;
    }

    public HouseBlend() {
        description="house blend coffee";
    }
}

デコレータ - 抽象基底クラス

/**
 * 装饰类 --> 调料
 */
public abstract class Condiment extends Beverage {
    public abstract String getDescription();

    public double cost() {
        return 0;
    }
}

デコレーター

/**
 * 装饰者 摩卡
 */
public class Mocha extends Condiment {
    Beverage beverage;

    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription()+" , Mocha";
    }
    public double cost(){
        return 0.20+beverage.cost(); //价格计算从内到外
    }
}
//其他装饰者类似 

starbuzzcoffeeを達成

public class StarbuzzCoffee {
    public static void main(String[] args) {
        Beverage beverage=new Espresso();//浓缩咖啡 被装饰对象
        System.out.println(beverage.getDescription()+" "+beverage.cost()); //Espresso--浓缩咖啡 1.99

        //开始装饰
        beverage=new Mocha(beverage);//加上Mocha
        System.out.println(beverage.getDescription()+" "+beverage.cost());//Espresso--浓缩咖啡 , Mocha 2.19

        beverage=new Sony(beverage);
        System.out.println(beverage.getDescription()+" "+beverage.cost());//Espresso--浓缩咖啡 , Mocha , Sony 2.49

        beverage=new Whip(beverage);
        System.out.println(beverage.getDescription()+" "+beverage.cost());//Espresso--浓缩咖啡 , Mocha , Sony , Whip 2.9

        //双倍Mocha
        beverage=new Mocha(beverage);
        System.out.println(beverage.getDescription()+" "+beverage.cost());//Espresso--浓缩咖啡 , Mocha , Sony , Whip , Mocha 3.1
    }
}

小さなカップ、カップ、マグカップを達成

public  abstract class CupSize extends Beverage {

    public  abstract String getDescription() ;
    @Override
    public double cost() {
        return 0;
    }
}
public class SmallCup   extends CupSize {
    Beverage beverage;

    @Override
    public String getDescription() {
        return beverage.getDescription()+" , 小杯 多收0.1";
    }

    @Override
    public double cost() {
        return beverage.cost()+0.1;
    }

    public SmallCup(Beverage beverage) {
        this.beverage = beverage;
    }
}

この例では、成分として、カップの大きさに相当しますが、質問は明らかである:3つのクラスがあります。増加に大きな価格|ミッド|書籍の例としては、サイズ==小さなを決定SizeDeクラスを、飾るためだけにして、スーパークラス飲料にsize属性に追加されます。

上記の質問残り:どのように委任するには?何を委託していますか?

私は理解:caffeeコンピューティングの価格は、コーヒーが実際に食材の委託を受けたので、コーヒーの価格は計算の食材の価格に最終的に依存しています。Caffeeの中の成分の成分を添加caffee(組成)(すなわち、デコレータ)に委託しました。これは、コストのメソッド呼び出しの層によって価格が生じました。

リリース9件のオリジナルの記事 ウォンの賞賛4 ビュー4247

おすすめ

転載: blog.csdn.net/qq_42239081/article/details/104869055