装点者模式——Decorator
装饰者模式—— Decorator
有时间还是看一下《 Java 设计模式》,临近期末,为了节省时间我直接找了一些资料总结了一下。
1. Decorator 好处 / 目的 :
A. 如果使用继承 实现功能扩展:
我们通常使用继承来实现功能扩展,随着这些需要扩展的功能的增多,扩展功能的组合会导致更多的子类的膨胀。
同时,使用继承实现功能的扩展,我们必须可预见这些拓展功能,这些功能编译时就确定了,是静态的。
B. 如果使用 Decorator 实现功能扩展:
如果扩展功能需要由用户动态决定加入的方式和时机, Decorator 提供了“即插即用”的方法,即在运行期间决定何时增加何种功能。
这样,避免了在层次结构高层有太多的特征, Decorator 模式提供了一种“即插即用”的方法添加职责,他并不试图在一个复杂的可定制的类中支持所有可预见的特征;相反,可以定义一个简单的类,并且用 Decorator 类给他们逐渐添加功能,可以从简单的部件组合出复杂的功能。
总结: The intent of Decorator is to let you compose new variations of an operation at runtime .
2. 如何使用 Decorator :
图 . Decorator 模式
注意到,装饰者类 Decorator 既在①内部将被装饰者 Component 作为成员(保证请求的传递,不必实现 ConcreteComponent 已经实现的功能);又②实现了 Component 接口(保证客户端使用 Decorator 就如同使用 Component 一样)
3. Decorator 举例 :
实际上, Java 的 I/O API 就是使用 Decorator 实现的,如果采用继承的方式,将会产生很多很多子类!
下面仅通过一个简单的例子实现上面图中的功能。
客户端代码:
package decorator; public class Client { public static void main(String[] args) { Component component=new ConcreteComponent(); Component decorator=new Decorator(component); component.setName("小王"); System.out.println(component.getName()); decorator.setName("小王"); System.out.println(decorator.getName()); } }
被装饰者和被装饰者实现:
package decorator; public interface Component { public void setName(String name); public String getName(); } public class ConcreteComponent implements Component { String name; @Override public String getName() { return name; } @Override public void setName(String name) { this.name=name; } }
装饰者:
package decorator; public class Decorator implements Component { //如果有多个组件,可能用到private List<Component> list; private Component component; public Decorator(Component c){ component=c; } @Override public String getName() { /* * 在name前加上"名字是: "——这个效果就是装饰者达到的作用 */ return "名字是: "+component.getName(); } @Override public void setName(String name) { component.setName(name); } }
输出效果:
参见《设计模式》板桥里人 http://www.jdon.com 2002/04/28
参见 装饰模式 (Decorator) 解析例子 ,http://tianli.blog.51cto.com/190322/35287
参见《 Java 设计模式》