一、前言
装饰器模式是我们在设计中常用的一种设计模式,我们从模式的名字就大概能知道,这种设计模式的主要作用就是给某一个对象增加额外的职责,而这种装饰可以是多种的。就像我们给一个洋娃娃装饰它的衣物一样,这样就使得我们很容易理解这种设计模式扩展性非常好,灵活性也比较高。就增加功能来说,装饰器模式相比生成子类更为灵活。当我们在不想很多子类的情况下,我们可以考虑使用装饰器模式。
二、装饰器模式
概述:允许向一个现有的对象添加新的功能,同时又不改变其结构。 动态地给一个对象添加一些额外的职责。
装饰者模式的适用性:
1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2、处理那些可以撤消的职责。
3、当不能采用生成子类的方法进行扩充时。
装饰者模式其实就是对我们需要装饰的主体的一个包装,为这个主体动态的增加一些额外的职责。所谓动态就是这种装饰的职责可以随意更换,这样子可以使设计更加灵活,扩展性也非常强。
三、我们通过一个简单的奶茶订单系统来演示装饰者模式。
装饰器模式的结构一般都非常清晰,主要是三个部分 :主体、装饰类、装饰器,并且装饰类可以继续包装装饰类。
在这个系统中我们将一个价格抽取出来,因为装饰物品和主体都有价格的计算。价格计算通过递归的方式进行计算,在使用装饰器模式 中,最明显的就是装饰器这个类中需要有一个被装饰的属性,这个属性可以是主体,也可以是被包装过的主体。
代码展示:
3.1计算基类
public abstract class PriceBase {
private int price;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public PriceBase(int price) {
super();
this.price = price;
}
public abstract int cost();
}
3.2 主体,原味奶茶
public class MilkTea extends PriceBase{
public MilkTea(int price) {
super(price);
// TODO Auto-generated constructor stub
}
@Override
public int cost() {
// TODO Auto-generated method stub
System.out.println("原味价格:"+this.getPrice());
return this.getPrice();
}
3.3 装饰器类
public abstract class Decorator extends PriceBase{
private PriceBase priceBase;
public Decorator(int price,PriceBase priceBase) {
super(price);
// TODO Auto-generated constructor stub
this.priceBase = priceBase;
}
@Override
public int cost() {
// TODO Auto-generated method stub
message();
return this.getPrice()+this.priceBase.cost();
}
protected abstract void message();
protected void getTotalPrice()
{
System.out.println("==============");
System.out.println("总价格"+cost());
System.out.println("==============");
}
}
3.4 具体装饰类
/**
* 珍珠
* @author Deng
*
*/
public class Pearl extends Decorator {
public Pearl(int price, PriceBase priceBase) {
super(price, priceBase);
// TODO Auto-generated constructor stub
}
@Override
protected void message() {
// TODO Auto-generated method stub
System.out.println("加珍珠"+ this.getPrice());
}
/**
* 烧仙草
* @author Deng
*
*/
public class GrassJelly extends Decorator{
public GrassJelly(int price, PriceBase priceBase) {
super(price, priceBase);
// TODO Auto-generated constructor stub
}
@Override
protected void message() {
// TODO Auto-generated method stub
System.out.println("烧仙草"+this.getPrice());
}
}
3.5 结果展示
public class Test {
public static void main(String[] args) {
//主体
PriceBase base = new MilkTea(4);
base.cost();
//装饰类
Decorator decorator = new Pearl(2, base);
decorator.getTotalPrice();
Decorator decorator1 = new GrassJelly(4, base);
decorator1.getTotalPrice();
Pearl pearl = new Pearl(2, base);
Decorator decorator2 = new GrassJelly(4, pearl);
decorator2.getTotalPrice();
}
}
原味价格:4
==============
加珍珠2
原味价格:4
总价格6
==============
==============
烧仙草4
原味价格:4
总价格8
==============
==============
烧仙草4
加珍珠2
原味价格:4
总价格10
==============