设计模式-装饰者模式
1 模式动机
我们知道可以通过定义子类,在不改变现有代码的情况下,动态的扩展功能。如果因为子类过多或其它原因不能新建子类时,还可以通过新建装饰者的方式来动态的扩展功能。
2 模式定义
装饰模式(Decorator Pattern):以对客户端透明的方式动态地给一个对象附加上更多的责任。
3 模式分析
Component抽象构件:
可以是一个接口,也可以是抽象类,定义了统一的接口,其它角色均会实现。
ConcreteComponent具体构件:
被装饰的对象,提供一个基础的功能实现,在此基础上通过装饰者扩展功能。
Decorator装饰角色:
包含对Component统一接口的实现。
ConcreteComponent具体装饰角色:
包含对接口的具体装饰实现。
类图如下所示:
4 实例演示
package com.pattern.decorator;
// 所有炒饭的接口类
public interface Rice {
public int cost();
public String getDescription();
}
package com.pattern.decorator;
// 标准版炒饭实现类
public class EggRice implements Rice {
@Override
public int cost() {
// 标准版8元每份
return 8;
}
@Override
public String getDescription() {
return "Rice standard";
}
}
package com.pattern.decorator;
// 炒饭装饰者基类
public abstract class RiceDecorator implements Rice {
protected Rice rice = null;
public RiceDecorator(Rice rice) {
this.rice = rice;
}
@Override
public String getDescription() {
return rice.getDescription();
}
}
package com.pattern.decorator;
// 加蛋装饰器
public class EggDecorator extends RiceDecorator {
public EggDecorator(Rice rice) {
super(rice);
}
@Override
public int cost() {
// 加蛋加一元
return rice.cost() + 1;
}
}
package com.pattern.decorator;
// 加肉装饰器
public class MeatDecorator extends RiceDecorator {
public MeatDecorator(Rice rice) {
super(rice);
}
@Override
public int cost() {
// 加肉加两元
return rice.cost() + 2;
}
}
package com.pattern.decorator;
public class RiceTest {
public static void main(String args[]) {
// 计算加肉加蛋后的炒饭价格
Rice theRice = new EggRice();
// 加肉加两个鸡蛋
Rice myRice = new MeatDecorator(new EggDecorator(new EggDecorator(theRice)));
System.out.println("Price(standard):"+theRice.cost());
System.out.println("Price(two eggs and one meat):"+ myRice.cost());
}
}
5 优缺点
优点:
1 可以扩展对象的功能,提供比继承更多的灵活性。
2 可以使用不同的装饰类来达到很多不同行为的组合。
缺点:
1 比继承更加复杂
2 会导致设计中出现许多小类,如果过度使用,会使程序变得复杂
6 适用环境
1 需要增加一些由基本功能的排列组合而产生的大量功能,可能导致子类爆炸性的增加,从而使得继承关系变得不现实。
2 类定义为不能生成子类,不能通过直接继承扩展。
7 总结
1 当无法通过继承进行扩展,可以考虑通过装饰扩展,其实就是通过组合和委托扩展。
2 装饰者可以在被装饰者行为的前面或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,从而达到特定的目的。
3 装饰者会导致设计中出现许多小对象,如果过度使用,会让程序变得很复杂。
浙公网安备 33010602011771号