c++ - 多态工厂

标签 c++ design-patterns abstract-factory

考虑以下代码:

template <typename T>
class DrawerFactory
{
protected:
    DrawerFactory() {};
private:
    virtual shared_ptr<IDrawer> GetDrawer(T settings) = 0;
};

class ConcreteDrawerFactoryA : public DrawerFactory<SettingsA>
{
public:
    shared_ptr<IDrawer> GetDrawer(SettingsA settingsA) override
    {
        if (settingsA.style == A) return make_shared<ConcreteDrawerA>(settingsA.length, settingsA.stroke, settingsA.opacity);
        else return make_shared<ConcreteDrawerB>(20, .5);
    };
};

class ConcreteDrawerFactoryB : public DrawerFactory<SettingsB>
{
public:
    shared_ptr<IDrawer> GetDrawer(SettingsB settingsB) override
    {
        if (settingsB.type == TYPEC) return make_shared<ConcreteDrawerC>(settingsB.width, settingsB.height);
        else return make_shared<ConcreteDrawerD>(10, 2);
    };
};

我可以通过以下方式获得一个抽屉:

ConcreteDrawerFactoryA().GetDrawer(settingsa);

ConcreteDrawerFactoryB().GetDrawer(settingsb);

我想做的是:

DrawerFactory().GetDrawer(settingsa);
DrawerFactory().GetDrawer(settingsb);

有没有一种方法可以设置它,而不必为我想添加的每个具体工厂不断地向 DrawerFactory 添加重载?

最佳答案

您可以使用模板和特化来代替工厂层次结构和虚拟分派(dispatch):

#include <memory>

struct IDrawer { };
struct Drawer1: IDrawer { };
struct Drawer2: IDrawer { };
struct Drawer3: IDrawer { };
struct Drawer4: IDrawer { };

template <class T>
struct DrawerGetterImpl;

struct DrawerFactory {
    template <class T>
    std::shared_ptr<IDrawer> GetDrawer(T settings) {
        return DrawerGetterImpl<T>::GetDrawer(settings);
    }
};

struct SettingsA { int style; };

template <>
struct DrawerGetterImpl<SettingsA> {
    static std::shared_ptr<IDrawer> GetDrawer(SettingsA settings) {
        if (settings.style == 1) {
            return std::make_shared<Drawer1>();
        }
        return std::make_shared<Drawer2>();
    }
};

struct SettingsB { int type; };

template <>
struct DrawerGetterImpl<SettingsB> {
    static std::shared_ptr<IDrawer> GetDrawer(SettingsB settings) {
        if (settings.type == 1) {
            return std::make_shared<Drawer3>();
        }
        return std::make_shared<Drawer4>();
    }
};

int main() {
    DrawerFactory().GetDrawer(SettingsA{1});
}

[live demo]

关于c++ - 多态工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41286072/

相关文章:

java - 创建发布-订阅模式以集成到 DAO 模式

oop - 一个存储库可容纳更多实体?

java - 游戏开发中的几种敌人 Action

java - 将 Java ThreadFactory 创建的对象的所有引用置为 null 的方法

python - opencv绘制矩形函数在C++、python中的行为不同

c++ - 将整数除以无符号长整数 - 是否存在编译时错误/警告?

C++:动态增长二维数组

java - java 中的工厂模式和泛型

php - 允许使用 PHP 中的抽象工厂模式进行自定义类实例化

c++ - 如何避免在 C++11 服务器程序中为多个客户端使用多线程