装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性。
装饰者模式介绍:
适用性:
1. 需要扩展一个类的功能,或给一个类添加附加职责。
2. 需要动态的给一个对象添加功能,这些功能可以再动态的撤销。
3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变的不现实。
4. 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
角色:
(1)抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
(2)具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
(3)装饰(Decorator)角色:持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。
(4)具体装饰(Concrete Decorator)角色:负责给构件对象添加上附加的责任。
UML图:
案例介绍:
我们应该都是吃过肉夹馍和手抓饼。假如一个摊贩贩卖这两种商品,而这两种商品都是由基础价格加上配料,形成最终的价格。
首先看下流程图:
代码示例:
创建煎饼抽象类:
package com.tian.decorator;
/**
* 煎饼抽象组件
* @author Administrator
*
*/
public abstract class BatterCake {
protected String desc = "";
public String getDesc() {
return desc;
}
public abstract double price();
}
手抓饼实现类:
package com.tian.decorator;
/**
* 手抓饼的实现类
* @author Administrator
*
*/
public class HandCake extends BatterCake {
public HandCake() {
this.desc = "手抓饼";
}
@Override
public double price() {
return 3f;
}
}
肉夹馍的实现类:
package com.tian.decorator;
/**
* 肉夹馍的实现类
* @author Administrator
*
*/
public class Roujiamo extends BatterCake {
public Roujiamo() {
this.desc = "肉夹馍";
}
@Override
public double price() {
return 5;
}
}
配料抽象类:
package com.tian.decorator;
/**
* 配料抽象类
* @author Administrator
*
*/
public abstract class Ingredient extends BatterCake{
public abstract String getDesc();
}
煎蛋的实现类:
package com.tian.decorator;
public class FireEgg extends Ingredient {
private BatterCake batterCake;
private String desc;
private double price;
public FireEgg(BatterCake batterCake,String desc,double price) {
this.batterCake = batterCake;
this.desc = desc;
this.price = price;
}
@Override
public String getDesc() {
return batterCake.getDesc() + desc;
}
@Override
public double price() {
return batterCake.price() + price;
}
}
肉片实现类:
package com.tian.decorator;
public class MeatFloss extends Ingredient {
private BatterCake batterCake;
private String desc;
private double price;
public MeatFloss(BatterCake batterCake,String desc,double price) {
this.batterCake = batterCake;
this.desc = desc;
this.price = price;
}
@Override
public String getDesc() {
return batterCake.getDesc() + desc;
}
@Override
public double price() {
return batterCake.price() + price;
}
}
测试类:
package com.tian.decorator;
public class DecoratorTest {
public static void main(String[] args) {
BatterCake handCake = new HandCake();
System.out.println(handCake.getDesc() + handCake.price());
BatterCake roujiamo = new Roujiamo();
roujiamo = new FireEgg(roujiamo, "煎蛋", 1);
roujiamo = new MeatFloss(roujiamo, "肉片", 5);
System.out.println(roujiamo.getDesc() + roujiamo.price());
}
}