我们应该在C++中使用decorator模式吗

本文关键字:decorator 模式 C++ 我们 | 更新日期: 2023-09-27 18:25:19

毫无疑问,decorator模式是一个很好的、简单的标准,可以增强类中一些不能(或不应该)继承旧方法的方法,比如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代码搞砸。但这也可以通过多重继承来实现。

所以,你能解释一下(或者举个例子)在哪里装饰比多重继承更好吗?

我们应该在C++中使用decorator模式吗

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

此外,如果您继承的不是接口类(只有纯虚拟方法的类),那么很难正确进行多重继承。

在我看来,这不是装饰器模式,您似乎使用了错误的继承方式。在继承之前,问问自己,如果这句话成立:"儿子是父亲"或SpecificObject是泛化对象,这不是你想要表达的。

decorator模式的工作原理是将要装饰的对象传递给装饰它的对象。一个典型的例子是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);
       }
   }

希望这对有帮助