C++中的工厂模式 - 正确执行此操作?

San*_*nto 12 c++ design-patterns interface factory-pattern

我对"设计模式"相对较新,因为它们在正式意义上被提及.我很久没有成为一名专业人士,所以我对此很陌生.

我们有一个纯虚拟接口基类.这个接口类显然是提供了派生子进程应该做什么功能的定义.软件中的当前用法和情况决定了我们想要使用什么类型的派生子,因此我建议创建一个包装器,它将传达我们想要的派生子类型,并返回指向新派生对象的Base指针.据我所知,这个包装器是一个工厂.

好吧,我的一位同事在Base类中创建了一个静态函数来充当工厂.这有两个原因导致我麻烦.首先,它似乎打破了Base类的接口性质.我认为界面本身需要知道从中衍生出来的孩子,这对我来说是错误的.

其次,当我尝试在两个不同的Qt项目中重用Base类时,会导致更多问题.一个项目是我实现第一个(可能只是这个类的真正实现......虽然我想对其他两个具有几个不同派生类的特性使用相同的方法)派生类,第二个是实际最终将使用我的代码的应用程序.在我编写代码时,我的同事创建了一个派生类,作为真实应用程序的测试人员.这意味着我必须将他的标题和cpp文件添加到我的项目中,这似乎是错的,因为我在实现我的部分时甚至没有使用他的代码用于项目(但是当它完成时他将使用我的).

我是否正确认为工厂真的需要成为Base类的包装而不是作为工厂的Base?

Zac*_*and 16

您不希望将接口类用作工厂类.首先,如果它是一个真正的接口类,则没有实现.其次,如果接口类确实定义了一些实现(除了纯虚函数),那么创建静态工厂方法现在会强制每次添加子类实现时重新编译基类.

实现工厂模式的最佳方法是将您的接口类与工厂分开.

下面是一个非常简单(不完整)的例子:

class MyInterface
{
public:
    virtual void MyFunc() = 0;
};

class MyImplementation : public MyInterface
{
public:
    virtual void MyFunc() {}
};

class MyFactory
{
public:
    static MyInterface* CreateImplementation(...);
};
Run Code Online (Sandbox Code Playgroud)

  • @Eamon:不,你不能按值返回抽象基类; 工厂必须返回指针,智能或其他. (4认同)
  • @Eamon:以及Zac所说的,在一个不垃圾的设计中,使用界面的东西可能比使用工厂更多,因为有些东西会把对象作为参数并对它们起作用,但不会创建对象本身.因此,您可以通过确保仅需要接口的东西也不依赖于工厂函数来减少耦合/依赖性.从根本上说,"工厂"功能的概念是有缺陷的.如果接口是一个有价值的抽象,那么创建实现它的对象可能有多种可能的方法. (4认同)
  • +1虽然,我希望看到*CreateImplementation*返回的smart_ptr或副本,而不是原始指针. (2认同)