装饰者模式(又称装饰模式、包装(Wrapper)模式):动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。
以下情况使用Decorator模式(摘自《设计模式》):
• 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
• 处理那些可以撤消的职责。
• 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
——抽象构件角色(Component)
给出一个个抽象接口,以规范准备接收附加责任的对象。是被装饰类和装饰类的父接口。
——具体构建角色(Concrete Component)
定义一个将要接受附加责任的类,即被装饰的类。
——装饰角色(Decorator)
装饰者,持有一个构件(Component)对象的引用,并定义一个与抽象构件接口一致的接口。
——具体装饰角色(Concrete Decorator)
具体装饰者,负责给构件对象“贴上”附加的责任(扩展功能)
public interface Component
{
public void doSomething();
}
public class ConcreteComponent implements Component
{
@Override
public void doSomething()
{
System.out.println("功能 A");
}
}
(具体构件可以单独使用)
public class Decorator implements Component
{
//持有一个Component类型的引用,可以包装具体构件或装饰者(只要实现了Component接口)
Component component;
public Decorator(Component component)
{
this.component=component;
}
@Override
public void doSomething()
{
this.component.doSomething();
}
}
public class ConcreteDecoratorA extends Decorator
{
public ConcreteDecoratorA(Component component)
{
super(component);
}
@Override
public void doSomething()
{
super.doSomething();
this.doAnotherThing();
}
public void doAnotherThing()
{
System.out.println("功能 B");
}
}
public class ConcreteDecoratorB extends Decorator
{
public ConcreteDecoratorB(Component component)
{
super(component);
}
@Override
public void doSomething()
{
this.doAnotherThing();
super.doSomething();
}
public void doAnotherThing()
{
System.out.println("功能 C");
}
}
public class Client
{
public static void main(String[] args)
{
//具体构件
Component component = new ConcreteComponent();
// 具体装饰者装饰具体构件
Component decorator = new ConcreteDecoratorA(component);
decorator.doSomething();
// 具体装饰者可以装饰具体装饰者(实际上它并不知道)
Component decorator2 = new ConcreteDecoratorB(decorator);
decorator2.doSomething();
}
}
设计原则:类应该对扩展开放,对修改关闭。
装饰者模式完全遵循开放-关闭原则,装饰者可以在被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的(此即扩展),并且不用修改被装饰者的代码(此即关闭)。这样使得所设计的系统更具有弹性,可以接受新的功能来应付变化的需求。
对于java.io.OutputStream、java.io.Reader和java.io.writer也是如此
1.装饰者和被装饰者对象具有相同的超类型,所以在任何使用被装饰者对象的场合,可以用装饰过的对象来代替它。(所以装饰者类反映出被装饰的组件的类型)
2.装饰者不仅可以装饰具体构件,还可以装饰装饰者。
3.装饰者和被装饰者都继承(或实现)自相同的超类型(Component),我们是利用继承达到“类型匹配”,而不是利用继承获得“行为”。当我们将装饰者与组件(或装饰者)组合时,加入的新的行为并不是继承自超类,而是由组合对象(ConcreteComponent或ConcreteDecorator)得来的。
4.虽然装饰者模式可以为设计注入弹性,但装饰者也常常造成设计中有大量的小对象,如果过度使用会让程序变得很复杂。
5.装饰模式VS继承:装饰模式是使用组合和委托用来扩展特定对象的功能,不需要子类,动态地在运行时给对象加上新的行为,防止了由于子类而导致的复杂和混乱,具有更多的灵活性。而继承是用来扩展一类对象的功能,需要子类,静态地在编译时分派职责,导致了很多子类的产生,缺乏灵活性。
6.装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型
7.Decorator装饰者角色并不是必须的,当你仅需要添加一个职责时,没有必要定义抽象Decorator类。你常常需要处理现存的类层次结构而不是设计一个新系统,这时你可以把Decorator向Component转发请求的职责合并到Concrete Decorator中。
8.改变对象外壳与改变对象内核:我们可以将Decorator看作一个对象的外壳,它可以改变这个对象的行为。另外一种方法是改变对象的内核。例如, Strategy(策略)模式就是一个用于改变内核的很好的模式。
转载请注明出处:http://blog.csdn.net/jialinqiang/article/details/8881855