Java中的装饰器模式(Decorator)

目录

1 前言

2 装饰器模式简介

2.1 定义

2.2 模式类图

3 样例说明

3.1 样例

3.2 样例分析

3.3 代码实现


1 前言

Java中面向可复用性和可维护性的设计模式大体上分为三类:创建型模式(Creational patterns)、结构型模式(Structural patterns)、行为类模式(Behavioral patterns),本文将主要介绍结构型模式中的装饰器模式(Decorator pattern)。

 

2 装饰器模式简介

2.1 定义

一种用于代替继承的技术,无需通过继承增加子类就能扩展对象的新功能。使用对象的关联关系代替继承关系,更加灵活,同时避免类型体系的快速膨胀。

2.2 模式类图

装饰器模式的模式关系图可由下图来说明:

Java中的装饰器模式(Decorator)

 

3 样例说明

3.1 样例

假设你有多种Stack数据结构的拓展,具体包括以下三个子类:

UndoStack 一个让你撤销上一步push或pop操作的Stack
SecureStacck 一个需要密码的Stack
SynchronizedStack 一个序列化并发访问的Stack

 

此时需要有特性的任意组合,例如SecureUndoStack, SynchronizedUndoStack, SecureSynchronizedStack, SecureSynchronizedUndoStack,那我们应该如何来实现呢?

3.2 样例分析

如果此时我们选择以继承来实现的话,则模式图由下图所示:

Java中的装饰器模式(Decorator)

这会导致两个较大的问题:组合爆炸 和 大量代码重复 

而如果我们选择以装饰器模式来实现的话,则我们需要对每一个特性构造子类,通过委派机制增加到对象上,具体模式图如下:Java中的装饰器模式(Decorator)

此时,我们采用装饰器模式相较于静态的继承机制,我们就具有了更加灵活,可定制化的,紧密结合的延展了。

3.3 代码实现

The ArrayStack Class:

interface Stack{
    void push(Item e);
    Item pop();
}

public class ArrayStack implements Stack{
    ... //rep
    
    public ArrayStack() {...}
    public void push(Item e) {...}
    public Item pop() {...}
    
    ...
}

The AbstractStackDecorator Class:

public abstract class StackDecorator implements Stack {
    protected final Stack stack;
    public StackDecorator (Stack stack) {
        this.stack = stack;
    }
    public void push(Item e) {
        stack.push(e);
    }
    public Item pop() {
        return stack.pop();
    }
    
    ...
}  

The Concrete Decorator Classes:

public class UndoStack
        extends StackDecorator
        implements Stack {
    private final UndoLog log = new UndoLog();
    public UndoStack(Stack stack) {
        super(stack);
    }
    public void push(Item e) { 
        log.append(UndoLog.PUSH, e);
        super.push(e);
    }
    public void undo() {
        //implement decorator behaviors on stack
    }
    
    ...
}

这里我们需要注意的是super(stack) 和后面的 super.push(e),这里的super相当于是对装饰器中的方法的委派,而push方法中的log.append(UndoLog.PUSH, e)则是增加的新特性。

最后,我们使用decorator classes的方法如下:

//构造一个普通stack: 
Stack s = new ArrayStack();

//构造一个UndoStack: 
Stack t = new UndoStack(new ArrayStack());

//构造一个SecureSynchronizedUndoStack: 
Stack t = new SecureStack(
                  new SynchronizedStack(
                       new UndoStack(s)));

其中,值得注意的是最后构造具有多种特性的object时,我们需要通过一层一层的装饰来实现,其中具体机制如下图:

Java中的装饰器模式(Decorator)

上一篇:python 修饰器(decorator)


下一篇:【设计模式达摩院】03 装饰者模式本质内涵b