定义
动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式生成子类更灵活。
使用场景
需要透明且动态的扩展类的功能时
关键点
一个抽象组件角色—接口或抽象类,被装饰的原始对象
一个或多个具体组件—抽象组件的具体实现,被装饰的具体对象
一个抽象装饰角色—抽象类,装饰组件对像,持有组件对象引用
一个或多个具体装饰类—对抽象装饰者的具体实现
实现
/**
* 抽象组件
*/
public abstract class AbsComponent {
/**
* 抽象方法,自由定义
*/
public abstract void doSomething();
}
/**
* 具体组件A
*/
public class ConcreteComponentA extends AbsComponent {
@Override
public void doSomething() {
//具体组件A的逻辑实现
}
}
/**
* 具体组件B
*/
public class ConcreteComponentB extends AbsComponent {
@Override
public void doSomething() {
//具体组件B的逻辑实现
}
}
/**
* 抽象装饰—持有抽象组件(需要被装饰的组件可以动态注入)
*/
public class AbsComponentWrapper extends AbsComponent {
private AbsComponent component;
public AbsComponentWrapper(AbsComponent component) {
this.component = component;
}
@Override
public void doSomething() {
component.doSomething();
}
}
/**
* 组件A的具体装饰
*/
public class ComponentAWrapper extends AbsComponentWrapper {
public ComponentAWrapper(AbsComponent component) {
super(component);
}
@Override
public void doSomething() {
super.doSomething();
doSomethingA();
}
/**
* 自定义一系列的装饰方法
*/
public void doSomethingA() {
//装饰A组件
}
}
/**
* 组件B的具体装饰
*/
public class ComponentBWrapper extends AbsComponentWrapper {
public ComponentBWrapper(AbsComponent component) {
super(component);
}
@Override
public void doSomething() {
super.doSomething();
doSomethingB();
}
/**
* 自定义一系列的装饰方法
*/
public void doSomethingB() {
//装饰B组件
}
}
小结
1.装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
2.通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。
缺点
1.装饰模式比继承更加灵活机动的特性,同时意味着更加多的复杂性。
2.装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂。
3.装饰模式是针对抽象组件(Component)类型编程。但是,如果你=要针对具体组件编程时,就应该重新思考应用架构,以及装饰者是否合适。当然也可以改变Component接口,增加新的公开的行为,实现“半透明”的装饰者模式。在实际项目中要做出最佳选择。