装饰模式是23种设计模式之一,英文名叫Decorator Pattern,又叫装饰者模式。
装饰模式可以在不必改变原类文件和不使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。通过使用装饰模式,可以在运行时扩充一个类的功能。
原理是:增加一个装饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为装饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。装饰类必须和原来的类有相同的接口。
装饰模式是类继承的另外一种选择。
装饰模式与类继承的区别:类继承在编译时候增加行为,而装饰模式是在运行时增加行为。
当有几个相互独立的功能需要扩充时,这个区别就变得很重要。在有些面向对象的编程语言中,类不能在运行时被创建,通常在设计的时候也不能预测到有哪几种功能组合。这就意味著要为每一种组合创建一个新类。相反,装饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合。一个装饰模式的示例是JAVA里的Java I/O的实现。
装饰模式的UML如下:
装饰模式共涉及4个角色:
抽象构建角色(Component):该角色用于抽象需要装饰的对象,也就是原始对象。
具体构建对象(ConcreteComponent):该角色需要实现抽象构建角色的接口,是具体被装饰的原始对象,有自己的原始逻辑实现。
装饰角色(Decorator):该角色持有一个构建对象的实例,并定义一个与抽象构建角色一样的接口。
具体装饰角色(ConcreteDecorator):该角色用来装饰构建角色,是我们需要添加的装饰。
上述的角色代码实现如下:
抽象构建角色Component
public interface Component {
public void baseMethod();
}
具体构建角色ConcreteComponent
public class ConcreteComponent implements Component {
@Override
public void baseMethod() {
// TODO Auto-generated method stub
//sth to do...
System.out.println("It is the basic action...");
}
}
装饰角色Decorator:
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void baseMethod() {
component.baseMethod();
}
}
具体装饰角色ConcreteDecorator
public class ConcreteDecorator extends Decorator {
public ConcreteDecorator(Component component) {
super(component);
}
private void decorateMethod() {
//sth you wa