Decorator 的应用

03-03-25 manbaum
Decorator 其实是很普通的技术,估计大家都在用它而没有把它抽象为一种模式而已。其核心就是对已有的实现中可覆盖的方法进行覆盖,以便增加新的功能。

如 banq 在 Decorator 中所述,为了在打桩前做些必要的准备工作,比方要在方型桩上先钉个钉子(即所谓修饰),实现如下所述:

public interface IPeg
{
    void Insert(String message);
}

public SquarePeg implements IPeg
{
    public void Insert(String message)
    {
        // ...
    }
}

public DecoratedSquarePeg extends SquarePeg
{
    private void AddNail()
    {
        // 加钉子 ...
    }

    public void Insert(String message)
    {
        AddNail();
        super.Insert(message);
    }
}
<p>

banq
2003-03-26 10:16
是这样,Decorator 用起来太普遍,我们不知不觉的就在用它。

manbaum
2003-04-03 12:18

上次我贴的的实现有个问题,就是如果有大量不同的桩(M 种)需要做各种不同的装饰(N 种),则需要 (M*N) 种的组合来实现Peg子类,显然不合理,所以改变为另一种方式实现修饰,这样只需要实现 (M+N) 种组合。如下所述:

public DecoratedPeg implements IPeg
{
    private IPeg _peg;
    public DecoratedPeg(IPeg peg)
    {
         _peg = peg;
    }

    private AddNail()
    {
         // ...
    }

    public void Insert(String message)
    {
        AddNail();
        _peg.Insert(message);
    }
}
<p>

这样,对于使用桩子的函数,如:

void DoSomeWork(IPeg peg)
{
    // ... get message ...
    peg.Insert(message);
}
<p>

并不需要知道桩子有没有修饰,你可以

DoSomeWork(new SquarePeg());

也可以

DoSomeWork(new DecoratedPeg(new SquarePeg()));

感觉上说, Decorator 和 Adapter 有类似的地方,都是对一个已经实现了的类进行了新的包装。但是 Decorator 是对实现的包装,而 Adapter 是对接口的包装。即:Decorator 没有改变原实现的接口,而改变了接口的实现方法;而 Adapter 则相反,改变了原实现的接口,却没有改变原实现的实现方法。

banq
2003-04-04 14:12
分析得很有道理

coollzh
2003-04-09 22:53
i feel this design pattern is like Delegate & Interface

jerrying
2003-04-16 11:46
Decorator与Proxy在实现方式上很象

goldenypb
2003-04-28 14:06
谢谢

xuruihao
2003-08-28 15:26
我觉得这段代码是不是Decorator模式还有得商量...

Decorator模式最根本的目标是为Decoratee动态得刷上新的功能,是代替继承的一种选择.上面的这例子通过super.Insert()和自己定义的增值功能来达到为Decortee增加功能的目的,但是任何一个继承自父类的子类都是可以通过super来调用父类的功能的.我觉得Decorator模式最重要的一点是在Decorator抽象类中(如果没有Decorator抽象类的话就在具体Decorator类中)拥有一个被Decorate的类的实例(或者被Decorator的抽象类的实例),通过这个实例来调用父类的功能,而不是简单的通过super来调用.这样才能跟继承有真正的区别.

我的看法,不知道对不对?

rypan
2003-09-15 15:31
同意 xuruihao 的观点。

用钉子去装饰木桩并不恰当。有钉子的木桩可以当钉子使用吗?我觉得修饰模式简单一句话就是给名词加上形容词。

猜你喜欢