装饰者模式(Decorator)
意图: 动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。该模式以对客户端透明的方式扩展对象的功能。
适用环境
在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
处理那些可以撤销的职责。
当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
装饰模式中的角色:
抽象构件(Component): 是一个抽象类或接口,被装饰对象基类,可以给这些对象动态增加职责。
具体被装饰对象(ConcreteComponent): Component的实现类,最终要装饰的实际对象。
装饰者抽象类(Decorator): 是一个抽象类,继承或实现了Component的接口,同时它持有一个对Component实例对象的引用,也可以有自己的方法。
具体装饰(ConcreteDecorator): 是具体的装饰者对象,负责给ConcreteComponent附加责任。
代码示例:
主饮品为豆浆,配料为土鸡蛋、黑豆、糖,计算不同搭配的套餐价格
所需的文件为:
1个被装饰者接口文件(基类)
1个实现接口的具体被装饰者类
1个装饰者抽象类
3个装饰者实现类
1个测试类
测试类:
public class Test {
public static void main(String[] args) {
Drink drink = new SoyaBeanMilk();
EggDecorator egg = new EggDecorator(drink);
BlackBeanDecorator bb = new BlackBeanDecorator(egg);
SugarDecorator sd = new SugarDecorator(bb);
System.out.println("你需要的饮品为:"+sd.description());
System.out.println("所需价格为:"+sd.cost()+"元");
}
}
/**
运行结果:
你需要的饮品为:原味豆浆+土鸡蛋+黑豆+糖
所需价格为:10.0元
*/
Drink接口:
被装饰者的接口(基类)
package com.Decorator;
public interface Drink {
float cost();//计算价格
String description();//描述
}
SoyaBeanMilk类:
接口的具体实现类
具体的被装饰者类
package com.Decorator;
public class SoyaBeanMilk implements Drink{
@Override
public float cost() {
return 5f;
}
@Override
public String description() {
return "原味豆浆";
}
}
Decorator类:
装饰者抽象类
package com.Decorator;
public abstract class Decorator implements Drink {
private Drink drink;//契合点,第一次传入的是具体被装饰者对象
public Decorator(Drink drink) {
this.drink = drink;
}
@Override
public float cost() {
return drink.cost();
}
@Override
public String description() {
return drink.description();
}
}
BlackBeanDecorator类:
具体的装饰者对象
package com.Decorator;
public class BlackBeanDecorator extends Decorator {
public BlackBeanDecorator(Drink drink) {
super(drink);
}
@Override
public float cost() {
return super.cost()+2.0f;
}
@Override
public String description() {
return super.description()+"+黑豆";
}
}
EggDecorator 类:
具体的装饰者对象
package com.Decorator;
public class EggDecorator extends Decorator {
public EggDecorator(Drink drink) {
super(drink);
}
@Override
public float cost() {
return super.cost()+2.0f;
}
@Override
public String description() {
return super.description()+"+土鸡蛋";
}
}
SugarDecorator 类:
具体的装饰者对象
package com.Decorator;
//具体的装饰者对象
public class SugarDecorator extends Decorator {
public SugarDecorator(Drink drink) {
super(drink);
}
@Override
public float cost() {
return super.cost()+1.0f;
}
@Override
public String description() {
return super.description()+"+糖";
}
}