【问题标题】:How would you name this c++ design pattern你如何命名这个 c++ 设计模式
【发布时间】:2014-08-07 08:34:24
【问题描述】:

知道这可能是一个不恰当的问题(因为回复可能(将)仅基于个人的主观意见),我仍然冒险提出这个问题:

我们编写了一些代码并提出了以下构造

#include <iostream>
#include <string>

class Generic
{
public: virtual void do_work() = 0;
};

class SomeAppDescriptor : public Generic
{
public: static std::string name() { return "SomeAppDescriptor"; }
};

template <class TGenericApp> 
class CommonFunctionalities : public TGenericApp
{
public: void do_common_work() {
            std::cout << "do_common_work for " << TGenericApp::name();
        }
};

class RealClass : public CommonFunctionalities<SomeAppDescriptor>
{
public: virtual void do_work() {
            do_common_work();
            std::cout << "and doing the work" << std::endl;
        }
};

int main(int argc, char const *argv[])
{
    RealClass a;
    a.do_work();
    return 0;
}

现在我们处于文档阶段...我们需要为结构命名,其中CommonFunctionalities 继承自模板成员...并使用SomeAppDescriptor 的属性,这实际上是模板成员...如果要命名此构造,它的合适名称是什么?

编辑

主要思想是有很多AppDescriptor类从配置文件中读取一些数据(名称、ip、数据库等...),还有一个中间层(这里用@表示987654328@ 完成工作(但在某些模糊点,CommonFunctionalities 对象被映射到name()(字符串和通用映射)以获得do_work() 的功能),最后有人来自某处正在调用Genericdo_work,它在一组“上”层类(RealClass)中实现

【问题讨论】:

标签: c++ design-patterns


【解决方案1】:

在我看来,这就像对 Decorator 的拙劣尝试。

  • SomeAppDescriptorCommonFunctionalities 不会覆盖 do_work,因此它们不需要从 Generic 继承;但是,do_common_work 的使用表明这可能很有用。
  • 如果RealClass直接继承自Generic,则可以通过组合取CommonFunctionalities

使用装饰器模式,我最终会得到:

class Generic { public: virtual void do_work() = 0; };

template <typename App>
class CommonFunctionalities: public Generic {
public:
    virtual void do_work() override {
        std::cout << "CommonFunctionalities - " << App::name() << "\n";
    }
};

class RealClass: public Generic {
public:
    RealClass(std::unique_ptr<Generic> p): previous(std::move(p)) {}

    virtual void do_work() override {
        if (previous) { previous->do_work(); }
        std::cout << "RealClass\n";
    }

private:
    std::unique_ptr<Generic> previous;
};

int main() {
    RealClass rc{std::make_unique< CommonFunctionalities<SomeAppDescriptor> >()};

    Generic& g = rc;
    g.do_work();

    return 0;
}

装饰器是专门为工作分层而创建的,没有任何类比接口类了解更多,因此您可以在运行时选择要使用的层。即使不需要运行时灵活性,使用这种方法仍然是有利的,因为它减少了依赖关系:RealClass 不知道CommonFunctionalities

注意:在 C++ 中,借助模板,您还可以使用不带接口的 Decorator 方法。

【讨论】:

    【解决方案2】:

    【讨论】:

    • 使用 CRTP,但比直接CRTP更复杂;这在设计模式中很常见,通常应用程序设计会使用其中的几个
    【解决方案3】:

    我认为这是对Curiously Recurring Template Pattern 的升级。

    看起来不错。 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-13
      • 1970-01-01
      • 2021-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多