装饰器模式(Decorator)

来源:互联网 发布:unity3d vector2 编辑:程序博客网 时间:2024/05/16 07:18

装饰器模式

概念

装饰器模式(Decorator)也叫包装器模式(Wrapper),属于结构型模式,用于动态的为对象添加功能。通常情况下给对象添加功能,要么直接修改对象,要么使用继承来扩展,也可以使用组合的方式。直接修改对象的方式显然是不合适的,如果使用继承的方式,极有可能会导致子类膨胀。在面向对象的设计中,一般使用组合的方式来扩展对象的功能。装饰器模式就是使用组合的方式来代替类继承的方式以扩展对象的功能,使得更加灵活,也避免了类型的快速膨胀。

类图

装饰器模式

角色

Component:组件对象的接口,可以给这个对象动态的添加职责
ConcreteComponent:具体的组件对象,实现了组件的接口,该对象通常用作被装饰器装饰的原始的对象,可以给这个对象添加职责
Decorator:装饰器的父类,需要与组件接口一致,这里继承自Component主要是因为需要一个装饰器也可以被另一个装饰器装饰。
ConcreteDecorator:具体的装饰器类,实现具体要像被装饰对象添加的功能,用于装饰具体的组件对象或者另外一个具体的装饰器对象。

实例

Component对象

public abstract class Component {    public abstract void operation();}

ConcreteComponent对象

public class ConcreteComponent extends Component {    public void operation() {        System.out.println("ConcreteComponent::operation");    }}

Decorator对象

public abstract class Decorator extends Component {    protected Component component;    public Decorator(Component component) {        this.component = component;    }    public abstract void operation();}

ConcreteDecoratorA对象

public class ConcreteDecoratorA extends Decorator {    public ConcreteDecoratorA(Component component) {        super(component);    }    public void operation() {        System.out.println("ConcreteDecoratorA::operation");        component.operation();    }}

ConcreteDecoratorB对象

public class ConcreteDecoratorB extends Decorator {    public ConcreteDecoratorB(Component component) {        super(component);    }    public void operation() {        System.out.println("ConcreteDecoratorB::operation");        component.operation();    }}

Client对象

public class Client {    public static void main(String[] args) {        Component c = new ConcreteComponent();        Decorator dA  = new ConcreteDecoratorA(c);//给对象增加A功能        dA.operation();        Decorator dB = new ConcreteDecoratorB(dA);//给A添加B功能        dB.operation();    }}

优缺点

装饰器模式降低了系统的耦合度,可以动态的增加或者删除对象的功能,并需要装饰的具体的组件和装饰类可以独立变化,以便增加新的功能。

优点:

扩展对象功能,比继承灵活,避免了类膨胀
可以对一个对象进行多次装饰,创造出不同行为的组合,得到功能更加强大的对象
具体构建类和具体装饰类可以独立变化,用户可以根据需要自己增加新的具体构件子类和具体装饰子类

缺点:

产生很多小对象,大量小对象占据内存,一定程度上影响性能
装饰模式如果出错,调试比较困难

Java中的装饰器模式

Java中最经典的装饰器模式便是IO类簇了。Java的IO分为字节流和字符流,又可以分为输入流和输出流。

字节流 字符流 输入流 InputStream
StringBufferInputStream
FileInputStream
ByteArrayInputStream
PipedInputStream
ObjectInputStream
SequenceInputStream

FilterInputStream
BufferedInputStream
DataInputStream
PushbackInputStream Reader
PipedReader
CharArrayReader
BufferedReader
StringReader
InputStreamReader
FileReader

FilterReader
PushbackReader
输出流 OutputStream
ByteArrayOutputStream
FileOutputStream
ObjectOutputStream
PipedOutputStream

FilterOutputStream
DataOutputStream
BufferedOutputStream
Writer
PrintWriter
PipedWriter
CharArrayWriter
StringWriter
BufferedWriter
OutputStreamWriter
FileWriter

FilterWriter

Java 输入流

字节流:InputStream对应Component;StringBufferInputStream,FilteInputStream,ByteArrayInputStream,PipedInputStream,对应ConcreteComponent;FilterInputStream对应Decorator;BufferedInputStream,DataInputStream,PushbackInputStream对应ConcreteDecorator;
字符流:Reader对应Component;PipedReader,CharArrayReader,StringReader对应ConcreteComponent;FilterReader对应Decorator;PushbackReader对应ConcreteDecorator;
InputStreamReader用于将字节流封装成字符流

Java输出流
字节流:从类图中可以很明显的看出,OutputStream对应Component;ByteArrayOutputStream,FileInputStream,ObjectOutputStream,PipedOutputStream对应于ConcreteComponent;FilterOutputStream对应Decorator;DataOutputStream,BufferedOutputStream对应ConcreteDecorator;
字符流:writer对应Component;PipedWriter,StringWriter,CharArrayWriter对应ConcreteComponent;BufferedWriter,PrintWriter,FilterWriter对应Decorator;不过这里的BufferedWriter和PrintWriter也可以认为是ConcreteDecorator。

这里还有个OutputStreamWriter类,可以看出用于将字节流封装成字符流的。

Android中的装饰器模式

Android中的Context,ContextImpl,Activity等便是使用了装饰器模式
Android中的装饰器模式

这里的Context对应Component;ContextImpl对应ConcreteComponent;ContextWrapper对应Decorator;Service,Application,ContextThemeWrapper对应ConcreteDecortor。
ContextWrapper持有一个Context成员变量,再各个组件创建时会将ContextImpl赋给各个组件。

参考

设计模式(九)装饰器模式
装饰器模式(Decorator)

原创粉丝点击