一、装饰器模式的概念
装饰器模式:一种动态地往一个类中添加新的行为的设计模式,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。
原理:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法,修饰类必须和原来的类有相同的接口
说明:
Component[抽象组件]:定义一个可以动态添加行为的对象接口
ConcreteComponent[具体组件]:定义一个将要被装饰增加功能的类
Decorator[抽象装饰器]:维护一个指向Component的实例,并定义一个与Component一致的接口
ConcreteDecorator[具体装饰器]:向组件添加新职责
二、装饰器模式的实现
//抽象组件
public interface Component{
public void operation();
}
//具体组件(被装饰的对象)
public class ConcreteComponent implements Component{
public void operation(){
System.out.println("Just Do It.");
}
}
//抽象装饰器(持有抽象组件的引用)
//实现抽象组件的目的是对客户端透明
public abstract class Decorator implements Component{
protected Component component;
}
public class ConcreteDecorator extends Decorator{
public ConcreteDecorator(Component component){
this.component = component;
}
public void operation(){
System.out.println("No hesitation");
component.operation();
}
}
public class Test{
public static void main(String args[]) {
Component component = new ConcreteDecorator(new ConcreteComponent());
component.operation();
//outcome:
//No hesitation.
//Just Do It.
}
}
三、装饰器模式的应用
JAVA里的Java I/O Streams的实现
public static void main(String[] args) throws Exception
{
File file = new File("xxxxxx");
InputStream input = new FileInputStream(file);
InputStream inputBuffer = new BufferedInputStream(new FileInputStream(file));
}
四、装饰器の其他问题
修饰模式是类继承的另外一种选择,类继承在编译时候增加行为,而装饰模式是在运行时增加行为
当有几个相互独立的功能需要扩充时,这个区别就变得很重要
在有些面向对象的编程语言中,类不能在运行时被创建,也不能预测到有哪几种功能组合,意味着要为每一种组合创建一个新类
相反,修饰模式是面向运行时候的对象实例的,这样就可以在运行时根据需要进行组合
4.1 pros and cons:
装饰类和被装饰类都只关心自身的核心业务,实现了解耦
方便动态的扩展功能,且提供了比继承更多的灵活性
使用装饰器模式会产生比使用继承关系更多的对象
多层装饰比较复杂
4.2 装饰器模式与代理模式的区别
装饰器模式应当为所装饰的对象提供增强功能,而代理模式对所代理对象的使用施加控制,并不提供对象本身的增强功能。
五、Reference
六、Resource