Head First Design Patterns-- decorator pattern

Basic Introduction:
Decorator: Dynamic new functionality attached to the object, the target function expansion, it is more elastic than inheritance, Decorator also reflects the shutter principle (OCP), the decorator pattern can be understood as packing mode.

For example: We want to send a cell phone, send express our operations should be as follows:

① shock phone wrapped with the film, which is the first decorative layer
Here Insert Picture Description
② Next we express starting packaging box
Here Insert Picture Description
finally with plastic bags ③ good package
Here Insert Picture Description

Such a cell phone completes the package, the decorator pattern is such a principle, look at the following specific description:

  • FIG class represents
    Here Insert Picture Description

(1)Component

Defines an abstract class, for receiving a demand dynamically added.

(2)ConcreteComponent

ConcreteComponent we want to add a new dynamic behavior of objects.

(3)Decorator

Each instance of a decorator can hold a member (Component) object,

In other words, the decorator has an instance variable to hold a reference to a Component of

(4) ConcreteDecorator

The real decorator, responsible for the object to add new methods and behavior.

The first example:

Decorator is an abstract class: Beverage
was the decorator: Espresso, HouseBlend
decorator abstract class: CondimentDecorator
Decorator: Mocha

  • Specific implementation code
/**
 * 被装饰者的抽象类:饮料
 */
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());
    }
}
  • operation result
    Here Insert Picture Description

We found that wrote packaging work, you can achieve a packaging function!

  • FIG form class
    Here Insert Picture Description

A second example:

  • Structure chart
    Here Insert Picture Description
  • Code
/**
 * 被装饰者抽象类
 */
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());
    }
}
  • operation result
    Here Insert Picture Description
  • FIG form class
    Here Insert Picture Description

Java I / O

Here Insert Picture Description

  • From the JDK source code, we can find
//装饰者抽象类类继承了被装饰者: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 {

    ...
 }

summary:

1. decorator pattern means a group of decorator classes used to wrap concrete components.
2. decorator class reflects the type of components to be decorated (in fact, they have the same type, inheritance or interfaces have been achieved).
3. decorator adds the previous behavior can be decorator / or behind their behavior, even the behavior of the entire decorator substituted off, to achieve a specific purpose.
4. You can use an unlimited number of decorators packaging component.
The client component of the decorator is generally transparent, in particular depend on the type of the client unless the component.

Published 47 original articles · won praise 34 · views 8858

Guess you like

Origin blog.csdn.net/weixin_42893085/article/details/105397539