装饰模式
动态地给一个对象添加一些额外的职责。即为已有功能动态地添加更多功能的一种方式。
当一个对象所需的功能是动态变化,或者说是有着许多种组合(且可以有着一定的组合顺序)时,这时如果使用子类的方式则需要将这种组合的过程暴露在外面,且使得核心类的代码变得复杂。而使用装饰模式的话,它吧每个要装饰的功能放在单独的类中,然后让这个类去包装其所要装饰的对象。如此这般,客户代码就可以根据需要有选择、有顺序地使用装饰功能包装对象了。
所需的类:
- Component 对象接口类,有具体对象类的话也可以不用此接口
- ConcreteComponent 具体对象类(核心功能类)
- Decorator 装饰抽象类继承了对象接口类或者具体对象类
- ConcreteDecoratorA 具体的装饰类
代码实现:
Component(可以没有)
public abstract class Component {
public abstract void Operation();
}
ConcreteComponent(具体对象类)
public class ConcreteComponent extends Component{
@Override
public void Operation() {
// TODO Auto-generated method stub
//进行具体对象的核心功能操作
}
}
Decorator(装饰抽象类)
/**
* 如果只有ConcreteComponent则无需继承Component
* 直接继承自具体的ConcreteComponent类即可
*/
public abstract class Decorator extends Component{
protected Component component;
//利用此方法对对象进行包装
public void setComponent(Component component){ //设置Component
this.component = component;
}
@Override
public void Operation() {
// TODO Auto-generated method stub
if(component!=null){
component.Operation();
}
}
/** 这个方法供子类使用 */
public abstract void subOperation();
}
ConcreteDecoratorA(具体的装饰类)
public class ConcreteDecoratorA extends Decorator{
private String _string;
public void Operation() {
// TODO Auto-generated method stub
super.Operation(); //调用父类方法必须放在第一行
this._string = "独有功能";
System.out.println("ConcreteDecoratorA装饰对象A的操作");
}
}
Aplication
public class Application {
public static void main(String args[]){
/**
* 将装饰功能区与核心类分开了
*/
ConcreteComponent c = new ConcreteComponent();//核心功能类
ConcreteDecoratorA a = new ConcreteDecoratorA();
ConcreteDecoratorB b = new ConcreteDecoratorB();//装饰类
a.setComponent(c);//包装
b.setComponent(a);
b.subOperation(); /** 注意:执行是有顺序的 */
}
}
从代码中可以看出,装饰模式是利用setComponent方法来对对象进行包装的,如果没有Component只有一个ConcreteComponent的话则Decorator可以是ConcreteComponent的一个子类。