装饰者模式
简介
Decorator/Wrapper模式:动态将职责附加到对象上,若要扩展功能,装饰者提供了比继承更具弹性的代替方案。
表现形式
1. 装饰者和被装饰对象有相同的超类型。
2. 你可以用一个或多个装饰者包装一个对象。
3. 既然装饰者和被装饰对象有相同的超类型,所以在任何需要原始对象的场合,可以用装饰过的对象替代它。
4. 装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的。
5. 对象可以在任何时候被装饰,所以可以在运行时动态地、不限量地用你喜欢的装饰者来装饰对象。
设计原则
1. 聚合取代继承。利用继承设计子类的行为,是在编译时静态决定的,而且所有的子类都会继承到相同的行为。然而,如果能够利用组合的做法扩展对象的行为,就可以在运行时动态地进行扩展。
2. 类应设计的对扩展开放,对修改关闭。
角色
1. Component:抽象组件接口。
2. ConcreteComponent:具体组件类,扩展自Component,是我们将要动态附加新行为的对象,即被装饰者。
3. Decorator:装饰者抽象类(或接口),每一个装饰者都要有一个Component的引用并且实现Component接口,这里实现Component接口是为了保证装饰者和被装饰者有共同的超类,因为装饰者必须能取代被装饰者,持有一个Component是为了复用被装饰者的行为。
4. ConcreteDecorator:最终装饰者对象,实现的Component接口是通过复用被装饰者并扩展之后的。也可以有自己的扩展方法。
类图:
实例
Component
* Descrption: 组件接口:原始组件和装饰者对象都要继承自此 * To change this template use File | Settings | File Templates. */ public interface Component {
public void show();
} |
Horse
* Descrption: 具体组件对象:实现Component接口, * To change this template use File | Settings | File Templates. */ public class Horse implements Component { public void show() { System.out.println("我是一匹吉祥马"); } } |
Decorator
* Descrption: 装饰者对象: 实现Component接口,并持有一个Component对象,用聚合取代继承。 * 扩展一些自己的行为,供子类调用 * To change this template use File | Settings | File Templates. */ public abstract class Decorator implements Component{
protected Component component; //聚合Component,子类通过comopent已有的行为进行包装,扩展
public Component getComponent() { return component; }
public void setComponent(Component component) { this.component = component; }
public void happy() { System.out.println("Happy New Year!"); } } |
HorseWithMoney
* Descrption: 装饰者子类:继承Decorator * To change this template use File | Settings | File Templates. */ public class HorseWithMoney extends Decorator { public void show() { super.getComponent().show(); //复用已有的实现 System.out.println("我马上有钱"); //扩展对象的行为 } } |
HorseWithGirlFriend
* Descrption: 装饰者子类:继承Decorator * To change this template use File | Settings | File Templates. */ public class HorseWithGirlFriend extends Decorator { public void show() { super.getComponent().show(); System.out.println("我马上对象"); }
} |
HorseWithEveryThing
* Descrption: 装饰者子类:继承Decorator * To change this template use File | Settings | File Templates. */ public class HorseWithEveryThing extends Decorator { public void show() { super.getComponent().show(); System.out.println("我马上有一切"); }
} |
Client
* Descrption: 客户端对象 * To change this template use File | Settings | File Templates. */ public class Client { public static void main(String args[]) { Component horse = new Horse(); //定义一个组件本尊 Decorator decorator =new HorseWithMoney(); decorator.setComponent(horse);//复用本尊对象,聚合到decorator中 Decorator decorator1 =new HorseWithGirlFriend(); decorator1.setComponent(decorator); //由于decorator都实现了Component接口,所以也可以被聚合,这里就复用了decorator对象 Decorator decorator2 = new HorseWithEveryThing(); decorator2.setComponent(decorator1);
decorator.show(); decorator1.show(); decorator2.show(); } } |
适用性:
1. 需要扩展一个类的功能,或给一个类添加附属职责
优劣
优点:
1. 采用聚合的方式而不是继承的方式,扩展更加灵活
2. 具体装饰者对象又可以成为新的被装饰者,复用性非常好
缺点:
1. 灵活意味着复杂
2. 装饰者模式会导致出现很多小类,过度使用,程序会变得复杂。
推荐:http://www.cnblogs.com/god_bless_you/archive/2010/06/10/1755212.html