设计模式之装饰者模式

装饰者模式(Decorator)

1.基本介绍

  • 动态的将新功能附加到对象上,在功能扩展方面,它比继承更有弹性,体现了开闭原则

2.原理

1.原理类图

2.分析

装饰者模式就像是打包一个快递,要寄送的物品为主体,即被装饰类,包装即为装饰类,对主体进行包装

  • Component :被装饰的主体
  • ConcreteComponent:被装饰的具体的主体
  • Decorator:装饰者
  • 在Component 和ConcreteComponent之间还可以设计一个缓冲层,创建一个公共类抽象出各个ConcreteComponent的公共特点

3.案例

装饰者模式实现类图

角色分析

  • Drink是装饰者的抽象类,Component
  • ShortBlack就是单品咖啡
  • Decortor是一个装饰类,含有一个被装饰的对象(Drink obj)
  • Decortor的cost方法进行一个费用的叠加计算,递归的计算价格

代码实现

Drink类

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() {
		// TODO Auto-generated method stub
		return getPrice();
	}
}

单品类的实现

public class LongBlack extends Coffee{
	public LongBlack() {
		setDes("LongBlack");
		setPrice(18.0f);
	}
}

装饰类Decortor

public class Decorator extends Drink{

	private Drink obj;

	public Decorator(Drink obj) {
		super();
		this.obj = obj;
	}

	@Override
	public float cost() {
		// TODO Auto-generated method stub
		return obj.cost() + super.getPrice();
	}

	@Override
	public String getDes() {
		// TODO Auto-generated method stub
		return super.getDes()+""+getPrice()+"&&"+obj.getDes();
	}
}

具体的调味品:组合了一个单品的咖啡

//具体的Chocolate,这里就是调味品 
public class Chocolate extends Decorator{

	public Chocolate(Drink obj) {
		super(obj);
		// TODO Auto-generated constructor stub
		setDes("巧克力");
		setPrice(3.0f);  //调味品的价格
	}

}

4.IO源码分析

结构图

分析

InputStream是一个抽象类,他具有多个子类(具体的主体,例如FileInputStream),属于装饰者模式中的主体角色,其中定义了许多抽象方法由子类来实现

public abstract class InputStream implements Closeable {

InputStream的子类FileInputStream,充当具体的主体类

public
class FileInputStream extends InputStream
{

FilterInputStream装饰者类,继承了InputStream,组合了一个InputStream,符合我们上述讲的装饰者角色

public
class FilterInputStream extends InputStream {
    /**
     * The input stream to be filtered.
     */
    protected volatile InputStream in;

而FilterInputStream的子类对InputStream进行了组合赋值,充当的是上述例子调味品的角色

public
class DataInputStream extends FilterInputStream implements DataInput {

    /**
     * Creates a DataInputStream that uses the specified
     * underlying InputStream.
     *
     * @param  in   the specified input stream
     */
    public DataInputStream(InputStream in) {
        super(in);
    }

如上介绍的模式在我们应用的时候则是这样的

//创建一个包含了主体InputStream的装饰类,将主体单品传入构造器,获得一个经过包装的FileInputStream对象,此时已经是DataInputStream对象了
DataInputStream dataInputStream = new DataInputStream(new FileInputStream(file));
posted @ 2020-06-26 14:36  J,IAT  阅读(160)  评论(0编辑  收藏  举报