在我的应用程序中,有10-20个类被实例化一次[*].这是一个例子:
class SomeOtherManager; class SomeManagerClass { public: SomeManagerClass(SomeOtherManager*); virtual void someMethod1(); virtual void someMethod2(); };
类的实例包含在一个对象中:
class TheManager { public: virtual SomeManagerClass* someManagerClass() const; virtual SomeOtherManager* someOtherManager() const; /** More objects... up to 10-20 */ };
目前,TheManager使用new运算符来创建对象.
我的目的是能够使用插件替换SomeManagerClass(或任何其他类)实现与另一个.为了取代实施,需要两个步骤:
定义一个DerivedSomeManagerClass类,它继承了SomeManagerClass [plugin]
创建新类(DerivedSomeManagerClass)而不是默认(SomeManagerClass)[application]
我想我需要某种对象工厂,但它应该相当简单,因为总是只有一种类型要创建(默认实现或用户实现).
有关如何设计像我刚刚描述的简单工厂的想法吗?考虑到将来可能会有更多类的事实,因此应该很容易扩展.
[*]我不在乎它是否不止一次发生.
编辑:请注意,TheManager中包含两个以上的对象.
假设一个继承自SomeManagerClass的类(plugin1),您需要一个类层次结构来构建您的类型:
class factory { public: virtual SomeManagerClass* create() = 0; }; class plugin1_factory : public factory { public: SomeManagerClass* create() { return new plugin1(); } };
然后,您可以将这些工厂分配给std :: map,它们绑定到字符串
std::mapfactory_map; ... factory_map["plugin1"] = new plugin1_factory();
最后你的TheManager只需要知道插件的名称(作为字符串),并且只需一行代码即可返回SomeManagerClass类型的对象:
SomeManagerClass* obj = factory_map[plugin_name]->create();
编辑:如果你不想为每个插件都有一个插件工厂类,你可以修改前面的模式:
templateclass plugin_factory : public factory { public: SomeManagerClass* create() { return new plugin_type(); } }; factory_map["plugin1"] = new plugin_factory ();
我认为这是一个更好的解决方案.此外,如果您将字符串传递给costructor,'plugin_factory'类可以将自身添加到'factory_map'.
我认为这里有两个不同的问题.
一个问题是:TheManager如何命名它必须创建的类?它必须保留某种指向"创建类的方法"的指针.可能的解决方案是
为每种类保留一个单独的指针,并设置它,但你已经说过你不喜欢它,因为它违反了DRY原则
保持某种表,其中键是枚举或字符串; 在这种情况下,setter是带参数的单个函数(当然,如果键是枚举,你可以使用向量而不是映射)
另一个问题是:这种"创建课程的方式"是什么?不幸的是我们不能直接存储指向构造函数的指针,但我们可以:
正如其他人所指出的,创造每个班级的工厂
只需为每个类添加一个静态"创建"函数; 如果他们保持一致的签名,你可以使用他们的指针功能
在这两种情况下,模板都可以帮助避免不必要的代码重复.