在星巴克咖啡中,随意的点取咖啡种类以及配料的场景,如果使用传统的逻辑控制,产出的将会是一片非常不优雅的代码,而几乎每个例子中都会使用这样的一个场景,来引出装饰者模式的介绍。
装饰者模式通常有着如下的特点:
1、装饰对象和被装饰对象通常有着相同的接口,实现相同的操作;
2、装饰者对象中要含有被装饰对象的实例;
3、装饰者只是增加了附加功能,而不会去更改被装饰对象的实现逻辑;
从上述的描述中,我们可以抽象一下几个领域模型:
1、共同的接口,装饰者和被装饰者会针对相同的应用场景进行逻辑功能的控制,所以势必需要一个共同的接口,来定义特定的解决问题的场景方法。
2、抽象组件。这个可以是被装饰者的抽象父类,这里其实是可以作为“模板模式”的一个切入点
3、抽象的装饰者,抽象了装饰者的通用特征,比如装载的被装饰对象。
小练习:
1、定义通用接口
/** * 抽象对象接口 * @author quzishen * @version 1.0 * @time 2011-3-4 */ public interface BaseCompnentFacade { /** * 执行方法体 */ public void execute(); /** * 增加装饰者的数量 */ public void addCount(); /** * 获取装饰者的数量 */ public int getCount(); }
2、定义被装饰者抽象父类
/** * base抽象对象 * @author quzishen * @version 1.0 * @time 2011-3-4 */ public abstract class BaseCompnent implements BaseCompnentFacade { // 名称 protected String compnentName; // 当前对象数量 protected int count; BaseCompnent(String compnentName, int count) { super(); this.compnentName = compnentName; this.count = count; } }
注意上述的获取装饰对象数量和设置装饰对象数量的方法纯属于本次测试使用,严格意义上讲,或许放入抽象接口不太适合
3、定义装饰者抽象父类
/** * base抽象装饰者 * @author quzishen * @version 1.0 * @time 2011-3-4 */ public abstract class BaseDecorator implements BaseCompnentFacade { /** * 装载着被装饰对象 */ protected BaseCompnentFacade baseCompnentFacade; BaseDecorator(BaseCompnentFacade baseCompnentFacade) { this.baseCompnentFacade = baseCompnentFacade; } /* (non-Javadoc) * @see com.head.first.decorator.BaseCompnentFacade#execute() */ public void execute() { baseCompnentFacade.execute(); } public void addCount() { baseCompnentFacade.addCount(); } public int getCount() { return baseCompnentFacade.getCount(); } }
看看他们的实现:
/** * 1号具体被装饰对象 * @author quzishen * @version 1.0 * @time 2011-3-4 */ public class NoOneCompnent extends BaseCompnent { NoOneCompnent(String compnentName, int count) { super(compnentName, count); } public void execute() { System.out.println(compnentName); } public void addCount() { count++; } public int getCount() { return count; } }
/** * 1号具体装饰者 * @author quzishen * @version 1.0 * @time 2011-3-4 */ public class NoOneDecorator extends BaseDecorator { NoOneDecorator(BaseCompnentFacade baseCompnentFacade) { super(baseCompnentFacade); } @Override public void execute() { addCount(); super.execute(); System.out.println("add NoOneDecorator!"); } }
/** * 2号装饰者 * @author quzishen * @version 1.0 * @time 2011-3-4 */ public class NoTwoDecorator extends BaseDecorator { NoTwoDecorator(BaseCompnentFacade baseCompnentFacade) { super(baseCompnentFacade); } @Override public void execute() { addCount(); super.execute(); System.out.println("add NoTwoDecorator!"); } }
测试方法
public class TestMain { /** * @param args */ public static void main(String[] args) { NoOneCompnent noOneCompnent = new NoOneCompnent("noOneCompnent", 0); BaseDecorator bd = new NoOneDecorator(noOneCompnent); bd = new NoTwoDecorator(bd); bd.execute(); System.out.println("装饰者的数量:" + bd.getCount()); } }
执行结果
noOneCompnent
add NoOneDecorator!
add NoTwoDecorator!
装饰者的数量:2