C++ 中的工厂模式——这样做正确吗?

发布于 2024-10-17 05:24:10 字数 609 浏览 2 评论 0原文

我对“设计模式”相对较新,因为它们是在正式意义上提到的。我成为专业人士的时间不长,所以对此还很陌生。

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

好吧,我的一位同事在基类中创建了一个静态函数来充当工厂。这给我带来了麻烦有两个原因。首先,它似乎打破了Base类的接口性质。我觉得界面本身需要了解从中派生的子元素的知识是错误的。

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

我是否正确地认为工厂确实需要成为 Base 类的包装器而不是充当工厂的 Base 类?

I am relatively new to "design patterns" as they are referred to in a formal sense. I've not been a professional for very long, so I'm pretty new to this.

We've got a pure virtual interface base class. This interface class is obviously to provide the definition of what functionality its derived children are supposed to do. The current use and situation in the software dictates what type of derived child we want to use, so I recommended creating a wrapper that will communicate which type of derived child we want and return a Base pointer that points to a new derived object. This wrapper, to my understanding, is a factory.

Well, a colleague of mine created a static function in the Base class to act as the factory. This causes me trouble for two reasons. First, it seems to break the interface nature of the Base class. It feels wrong to me that the interface would itself need to have knowledge of the children derived from it.

Secondly, it causes more problems when I try to re-use the Base class across two different Qt projects. One project is where I am implementing the first (and probably only real implementation for this one class... though i want to use the same method for two other features that will have several different derived classes) derived class and the second is the actual application where my code will eventually be used. My colleague has created a derived class to act as a tester for the real application while I code my part. This means that I've got to add his headers and cpp files to my project, and that just seems wrong since I'm not even using his code for the project while I implement my part (but he will use mine when it is finished).

Am I correct in thinking that the factory really needs to be a wrapper around the Base class rather than the Base acting as the factory?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

别挽留 2024-10-24 05:24:10

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

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

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

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

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

class MyFactory
{
public:
    static MyInterface* CreateImplementation(...);
};

You do NOT want to use your interface class as the factory class. For one, if it is a true interface class, there is no implementation. Second, if the interface class does have some implementation defined (in addition to the pure virtual functions), making a static factory method now forces the base class to be recompiled every time you add a child class implementation.

The best way to implement the factory pattern is to have your interface class separate from your factory.

A very simple (and incomplete) example is below:

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

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

class MyFactory
{
public:
    static MyInterface* CreateImplementation(...);
};
不可一世的女人 2024-10-24 05:24:10

我不得不同意你的观点。面向对象编程最重要的原则之一可能是对以下范围拥有单一责任一段代码(无论是方法、类还是命名空间)。在您的情况下,您的基类用于定义接口的目的。向该类添加工厂方法违反了该原则,打开了通向充满麻烦的世界之门。

I'd have to agree with you. Probably one of the most important principles of object oriented programming is to have a single responsibility for the scope of a piece of code (whether it's a method, class or namespace). In your case, your base class serves the purpose of defining an interface. Adding a factory method to that class, violates that principle, opening the door to a world of shi... trouble.

花海 2024-10-24 05:24:10

是的,接口(基类)中的静态工厂方法要求它了解所有可能的实例化。这样,您就无法获得工厂方法模式旨在带来的任何灵活性。

Factory应该是一段独立的代码,供客户端代码用来创建实例。您必须决定在程序中的某个地方创建什么具体实例。工厂方法允许您避免在客户端代码中传播相同的决策。如果稍后您想要更改实现(或例如用于测试),您只有一个地方可以编辑:这可能是例如通过条件编译(通常用于测试)或什至通过依赖项注入配置文件进行的简单全局更改。

请注意客户端代码如何传达它想要的实现类型:这并不是重新引入要隐藏的依赖项工厂的不常见方式。

Yes, a static factory method in the interface (base class) requires it to have knowledge of all possible instantiations. That way, you don't get any of the flexibility the Factory Method pattern is intended to bring.

The Factory should be an independent piece of code, used by client code to create instances. You have to decide somewhere in your program what concrete instance to create. Factory Method allows you to avoid having the same decision spread out through your client code. If later you want to change the implementation (or e.g. for testing), you have just one place to edit: this may be e.g. a simple global change, through conditional compilation (usually for tests), or even via a dependency injection configuration file.

Be careful about how client code communicates what kind of implementation it wants: that's not an uncommon way of reintroducing the dependencies factories are meant to hide.

枫以 2024-10-24 05:24:10

在类中看到工厂成员函数并不罕见,但这让我的眼睛流血。它们的使用通常与命名构造函数习惯用法的功能混合在一起。将创建函数移至单独的工厂类将为您带来更大的灵活性,以便在测试期间交换工厂。

It's not uncommon to see factory member functions in a class, but it makes my eyes bleed. Often their use have been mixed up with the functionality of the named constructor idiom. Moving the creation function(s) to a separate factory class will buy you more flexibility also to swap factories during testing.

花桑 2024-10-24 05:24:10

当接口只是为了隐藏实现细节并且基本接口只有一个实现永远时,可以将它们耦合起来。在这种情况下,工厂函数只是实际实现的构造函数的新名称。

不过,这种情况很少见。除非显式设计只有一个实现,否则您最好假设在某个时间点将存在多个实现,如果只是为了测试(正如您所发现的)。

所以通常最好将Factory部分拆分成一个单独的类。

When the interface is just for hiding the implementation details and there will be only one implementation of the Base interface ever, it could be ok to couple them. In that case, the factory function is just a new name for the constructor of the actual implementation.

However, that case is rare. Except when explicit designed having only one implementation ever, you are better off to assume that multiple implementations will exist at some point in time, if only for testing (as you discovered).

So usually it is better to split the Factory part into a separate class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文