我们应该在C ++中使用装饰模式吗?

时间:2012-02-22 10:18:23

标签: c# c++ design-patterns

毫无疑问,装饰器模式是一个好的,简单的标准来增强类中的一些方法,它不能(或不应该)继承旧方法,就像在C#中的这个例子(我不使用接口(我)应尽可能缩短。)

using System;

class Human { ... }

class Father {
    public string Info() {
        return "John";
    }
}

class Son : Human { // decorating Father
    Father f = new Father();
    public string Info() {
        return "I am son of "+f.Info();
    }
}


class Program {
    public static void Main() {
        Son s = new Son();
        Console.WriteLine(s.Info()); // I am son of John
        Console.ReadKey();
    }
}

但是由于我们在C ++中有多重继承,我们可以隐藏Fathers的Info()而不是装饰它:

#include <string>
#include <iostream>
using namespace std;

class Human { ... };

class Father {
public:
    string Info() {
        return "John";
    }
};

class Son : public Human, Father { // inherit both
public:
    string Info() {
        return "I am son of " + Father::Info();
    }
};

int main() {
    Son* s = new Son();
    cout << s->Info(); // I am son of John
    cin.get();
    return 0;
}

我理解许多模式的原因是将ad-hoc逻辑从可重用类移到ad-hoc类,因此可重用类不需要(或不能)与ad-hoc代码混淆。但这也可以通过多重继承来实现。

那么你能解释(或举一个例子)装饰比多重继承更好吗?

2 个答案:

答案 0 :(得分:4)

使用装饰器模式,您可以在运行时装饰对象,而多重继承是编译时解决方案。这允许您以最小的开销自由组合不同的装饰器,而对于多重继承,您需要为每个装饰器组合创建一个新类。

此外,如果继承除接口类(仅具有纯虚方法的类)之外的任何东西,则很难实现多重继承。

答案 1 :(得分:0)

在我看来,这不是装饰器模式,你似乎是以错误的方式使用继承。在继承之前,问问自己,如果语句成立:“Son是父亲”或者SpecialObject是一个GeneralizedObject,这不是你要表达的内容。

装饰器模式的工作原理是将要装饰的对象传递给装饰它的对象。一个典型的例子是Gui的BorderClass,它用边框装饰你传递它的小部件。

 public class Border : Widget
   { 
       public Border(Widget decorateMe)
       { 
          this._toDecorate = decorateMe;
       }
       public virtual void draw(gc or whatnot){
          gc.drawRectangle(blah);
          this._toDecorate.draw(gc);
       }
   }

希望这会有所帮助