ヘッドファーストデザインPatterns--のDecoratorパターン

基本的な概要:
デコレータ:物体に取り付けられた動的な新しい機能は、ターゲット機能拡張は、それが継承よりも弾性であり、デコレータはまた、シャッタ原理(OCP)を反映し、Decoratorパターンは次のように理解することができます梱包モード。

例えば:私たちは、携帯電話を送信する、送信は、次のように私たちの事業のあるべき表現します:

最初の装飾層であるフィルムで包ん①ショック電話、
ここに画像を挿入説明
②次に我々は箱のパッケージング開始を発現
ここに画像を挿入説明
ビニール袋で最後に③良いパッケージは、
ここに画像を挿入説明

このような携帯電話がパッケージを完了し、Decoratorパターンは、以下の具体的な説明では、このような原則、外観です。

  • 図クラスは表し
    ここに画像を挿入説明

(1)成分

動的に追加需要を受信するために、抽象クラスを定義します。

(2)ConcreteComponent

我々は、オブジェクトの新しい動的振る舞いを追加したいConcreteComponent。

(3)デコレータ

デコレータの各インスタンスは、部材(コンポーネント)オブジェクトを保持することができます

換言すれば、デコレータは、のコンポーネントへの参照を保持するインスタンス変数を有します

(4)ConcreteDecorator

オブジェクトの責任本当のデコレータは、新しい方法や動作を追加します。

最初の例:

デコレータは抽象クラスである:飲料は
デコレータた:エスプレッソ、HouseBlend
デコレータ抽象クラス:CondimentDecorator
デコレータ:モカ

  • 特定の実装コード
/**
 * 被装饰者的抽象类:饮料
 */
public abstract class Beverage {

    String description = "Unknown Beverage";

    //成本
    public abstract double cost();

    //得到描述信息
    public String getDescription(){
        return description;
    }
}

/**
 * 被装饰者:浓咖啡
 */
public class Espresso extends Beverage {

    public Espresso() {
        description = "Espresso";
    }

    @Override
    public double cost() {
        return 2;
    }
}

/**
 * 被装饰者:混合咖啡
 */
public class HouseBlend extends Beverage {
    public HouseBlend() {
        description = "House Blend";
    }

    @Override
    public double cost() {
        return 1;
    }
}

/**
 * 装饰者的抽象类:调料
 */
public abstract class CondimentDecorator extends Beverage {

    public abstract String getDescription();

    @Override
    public double cost() {
        return 0;
    }
}

/**
 * 装饰者:摩卡
 */
public class Mocha extends CondimentDecorator {

	//聚合被装饰者,可以传入实现Beverage接口的所有对象
    Beverage beverage;
	//构造器,初始化beverage
    public Mocha(Beverage beverage) {
        this.beverage = beverage;
    }

    @Override
    public String getDescription() {
        return beverage.getDescription()+",Mocha";
    }

    @Override
    public double cost() {
    	//调用被装饰者的成本,加上装饰者的成本
        return 3 + beverage.cost();
    }
}

/**
 * 测试
 */
public class CoffeeTest {
    public static void main(String[] args) {

        Beverage beverage = new Espresso();
        //一杯浓咖啡为2元
        System.out.println(beverage.getDescription()+","+beverage.cost());

        Beverage beverage1 = new HouseBlend();
        //一杯混合咖啡(1)加摩卡(3)为4元
        // 在单个混合咖啡中包装了摩卡
        beverage1 = new Mocha(beverage1);
        System.out.println(beverage1.getDescription()+","+beverage1.cost());

        //一杯混合咖啡(1)加摩卡(3)加摩卡(3)为7元
        //可以在包装好的基础上再次进行包装
        beverage1 = new Mocha(beverage1);
        System.out.println(beverage1.getDescription()+","+beverage1.cost());
    }
}
  • 業績
    ここに画像を挿入説明

私たちは、あなたがパッケージング機能を実現することができ、作業をパッケージに書いたことが判明しました!

  • 図フォームクラス
    ここに画像を挿入説明

第二の例:

  • Structureチャート
    ここに画像を挿入説明
  • コードの実装
/**
 * 被装饰者抽象类
 */
public abstract class Drink {

    public String des;//描述
    private float price = 0.0f;

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {
        this.price = price;
    }

    //计算费用的抽象 方法
    public  abstract float cost();
}

/**
 * 缓冲层
 */
public class Coffee extends Drink {
    @Override
    public float cost() {
        return super.getPrice();
    }
}

/**
 * 被装饰者:意大利咖啡
 */
public class Espresso extends Coffee {

    public Espresso(){
        setDes("意大利咖啡");
        setPrice(6.0f);
    }
}


/**
 * 装饰者抽象类:
 */
public class Decorator extends Drink {
    private Drink obj;

    public Decorator(Drink obj) {//组合
        this.obj = obj;
    }

    @Override
    public float cost() {
        //getPrice自己的价格
        return super.getPrice() + obj.cost();
    }


    public String getDes(){
        //obj.getDes()被装饰者的信息
        return super.des+" "+super.getPrice()+"&&"+obj.getDes();
    }
}


/**
 * 被装饰者:LongBlack
 */
public class LongBlack extends Coffee {
    public LongBlack() {
        setDes("LongBlack");
        setPrice(5.0f);
    }
}

/**
 * 被装饰者:ShortBlack
 */
public class ShortBlack extends Coffee {
    public ShortBlack() {
        setDes("ShortBlack");
        setPrice(4.0f);
    }
}

/**
 * 装饰者:
 */
public class Milk extends Decorator {
    public Milk(Drink obj) {
        super(obj);
        setDes("牛奶");
        setPrice(2.0f);
    }

}

/**
 * 装饰者:
 */
public class Soy extends Decorator {
    public Soy(Drink obj) {
        super(obj);
        setDes("豆浆");
        setPrice(1.5f);
    }
}

/**
 * 装饰者:
 */
public class Chocolate extends Decorator {

    public Chocolate(Drink obj) {
        super(obj);
        setDes("巧克力");
        setPrice(3.0f);
    }
}

public class CoffBar {
    public static void main(String[] args) {

        //1.点一份LongBlank
        Drink order = new LongBlack();
        System.out.println("费用1="+order.cost());
        System.out.println("描述="+order.getDes());
        
        //2.加一份牛奶
        order = new Milk(order);
        System.out.println("加入一份牛奶后的费用1="+order.cost());
        System.out.println("描述="+order.getDes());

        //3.加入一份巧克力
        order = new Chocolate(order);
        System.out.println("加入一份牛奶,一份巧克力后的费用1="+order.cost());
        System.out.println("描述="+order.getDes());
    }
}
  • 業績
    ここに画像を挿入説明
  • 図フォームクラス
    ここに画像を挿入説明

JavaのI / O

ここに画像を挿入説明

  • JDKのソースコードから、我々は見つけることができます
//装饰者抽象类类继承了被装饰者:InputStream 
public class FilterInputStream extends InputStream {
    /**
     * The input stream to be filtered.
     */
     //聚合了抽象组件componment
    protected volatile InputStream in;

    /**
     * Creates a <code>FilterInputStream</code>
     * by assigning the  argument <code>in</code>
     * to the field <code>this.in</code> so as
     * to remember it for later use.
     *
     * @param   in   the underlying input stream, or <code>null</code> if
     *          this instance is to be created without an underlying stream.
     */
    //利用构造方法初始化InputStream 
    protected FilterInputStream(InputStream in) {
        this.in = in;
    }
----------------------------------------------------------------------------------------
//被装饰者继承抽象类InputStream
public
class FileInputStream extends InputStream
{
    .......
}
----------------------------------------------------------------------------------------
//实际的装饰者继承装饰者抽象类
public
class DataInputStream extends FilterInputStream implements DataInput {

    ...
 }

要約:

1. Decoratorパターンは、コンクリート成分をラップするために使用されるデコレータクラスの基を意味します。
2.デコレータクラスは、(実際には、それらは同じタイプ、継承を有するか、またはインターフェイスが達成されている)に装飾されるべき部品の種類を反映しています。
3.デコレータは、以前の動作は、特定の目的を達成するために、デコレータ/またはその挙動、オフの置換全体デコレータのも、行動の背後に配置され追加されます。
4.コンポーネントをパッケージ化デコレータを無制限に使用することができます。
デコレータのクライアントコンポーネントは、特定のコンポーネントない限り、クライアントのタイプに依存し、一般的に透明です。

公開された47元の記事 ウォン称賛34 ビュー8858

おすすめ

転載: blog.csdn.net/weixin_42893085/article/details/105397539