C++ 如何设计一个简单的C++;对象工厂?
在我的应用程序中,有10-20个类被实例化一次[*]。下面是一个例子:C++ 如何设计一个简单的C++;对象工厂?,c++,factory,C++,Factory,在我的应用程序中,有10-20个类被实例化一次[*]。下面是一个例子: class SomeOtherManager; class SomeManagerClass { public: SomeManagerClass(SomeOtherManager*); virtual void someMethod1(); virtual void someMethod2(); }; 类的实例包含在一个对象中: class TheManager { public: vi
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 */
};
当前,管理器使用新操作符来创建对象
我的目的是能够使用插件将SomeManagerClass(或任何其他类)实现替换为另一个实现。为了替代实施,需要两个步骤:
编辑:请注意,Manager中包含两个以上的对象。您可以使用返回Manager类实例的静态方法实现对象工厂。在工厂中,您可以为默认类型的管理器创建一个方法,也可以为任何类型的管理器创建一个方法,您可以为这些管理器提供一个表示管理器类类型的参数(比如使用枚举)。最后一个方法应该返回接口而不是类 <>编辑:我会尝试给出一些代码,但是要注意我的C++时间相当长,我现在只做java和一些脚本。
class Manager { // aka Interface
public: virtual void someMethod() = 0;
};
class Manager1 : public Manager {
void someMethod() { return null; }
};
class Manager2 : public Manager {
void someMethod() { return null; }
};
enum ManagerTypes {
Manager1, Manager2
};
class ManagerFactory {
public static Manager* createManager(ManagerTypes type) {
Manager* result = null;
switch (type) {
case Manager1:
result = new Manager1();
break;
case Manager2:
result = new Manager2();
break;
default:
// Do whatever error logging you want
break;
}
return result;
}
};
现在,您应该能够通过(如果您已经能够使代码示例正常工作)呼叫工厂:
这是我想到的解决方案,它不是最好的,但也许它有助于想出更好的解决方案: 每个类都有一个creator类:
class SomeManagerClassCreator {
public:
virtual SomeManagerClass* create(SomeOtherManager* someOtherManager) {
return new SomeManagerClass(someOtherManager);
}
};
然后,创建者将聚集在一个类中:
class SomeManagerClassCreator;
class SomeOtherManagerCreator;
class TheCreator {
public:
void setSomeManagerClassCreator(SomeManagerClassCreator*);
SomeManagerClassCreator* someManagerClassCreator() const;
void setSomeOtherManagerCreator(SomeOtherManagerCreator*);
SomeOtherManagerCreator* someOtherManagerCreator() const;
private:
SomeManagerClassCreator* m_someManagerClassCreator;
SomeOtherManagerCreator* m_someOtherManagerCreator;
};
管理者将与创建者一起创建,用于内部创建:
class TheManager {
public:
TheManager(TheCreator*);
/* Rest of code from above */
};
这个解决方案的问题是它违反了DRY——对于每个类创建者,我都必须在创建者中编写setter/getter。Mh我没有百分之百的理解,我也不太喜欢书本和文章中的工厂内容
如果您的所有经理共享一个类似的接口,您可以从基类派生,并在程序中使用该基类。 根据将创建哪个类的决策将在何处做出,您必须使用标识符进行创建(如上所述),或者处理要在内部实例化哪个管理器的决策
另一种方法是像使用模板一样实现it“策略”。因此,您可以使用ManagerClass::create()返回特定的SomeOtherManagerWhatver实例。这将在使用您的经理的代码中确定要由哪个经理做出决定-可能这不是故意的 或者这样:
模板
类MyAwesomeClass
{
记忆管理m_记忆管理者;
};
(或诸如此类)
使用此构造,您只需更改MyAwesomeClass的实例化即可轻松使用其他管理器
同样,用于此目的的类可能有点过头了。在您的情况下,我想工厂函数就可以了。嗯,这更多的是个人偏好的问题。我会创建一个“基本”工厂,它有虚拟方法来创建所有基本管理器,并让“元管理器”(您问题中的管理器)将指向基本工厂的指针作为构造函数参数 我假设“工厂”可以通过从CXYZWManager派生来自定义CXYZWManager的实例,但CXYZWManager的构造函数也可以在“自定义”工厂中使用不同的参数 输出“CSomeManager”和“cderivedfromomemanager”的冗长代码示例:
#包括
//--------------------------------------------------------------------------------
班级经理
{
公众:
virtual const char*ShoutOut(){return“CSomeManager”;}
};
//--------------------------------------------------------------------------------
类协同热管理器
{
};
//--------------------------------------------------------------------------------
类管理器工厂
{
公众:
//非静态、非常量以允许多态性滥用
虚拟CSomeManager*CreateSomeManager(){返回新CSomeManager();}
虚拟协同管理器*CreateOtherManager(){返回新协同管理器();}
};
//--------------------------------------------------------------------------------
类CDerivedFromSomeManager:公共CSomeManager
{
公众:
virtual const char*ShoutOut(){返回“CDerivedFromSomeManager”;}
};
//--------------------------------------------------------------------------------
为CustomManagerFactory类:public TheManagerFactory
{
公众:
虚拟CDerivedFromSomeManager*CreateSomeManager(){返回新的CDerivedFromSomeManager();}
};
//--------------------------------------------------------------------------------
类管理器
{
公众:
CMETA经理(管理工厂*ip_工厂)
:mp\u some\u manager(ip\u工厂->CreateSomeManager()),
mp_其他_管理器(ip_工厂->CreateOtherManager())
{}
CSomeManager*GetSomeManager(){return mp\u some\u manager;}
COtherManager*GetOtherManager(){return mp_other_manager;}
私人:
CSomeManager*mp_some_manager;
共同经理*mp_其他_经理;
};
//--------------------------------------------------------------------------------
int _tmain(int argc,_TCHAR*argv[]
{
管理工厂标准工厂;
客户经理工厂客户工厂;
CMetaManager meta_manager_1(和标准_工厂);
CMetaManager meta_manager_2(和定制工厂);
std::cout ShoutOut()我会使用这样的模板,因为我看不见
class TheManager {
public:
TheManager(TheCreator*);
/* Rest of code from above */
};
template<class MemoryManagment>
class MyAwesomeClass
{
MemoryManagment m_memoryManager;
};
#include <iostream>
//--------------------------------------------------------------------------------
class CSomeManager
{
public:
virtual const char * ShoutOut() { return "CSomeManager";}
};
//--------------------------------------------------------------------------------
class COtherManager
{
};
//--------------------------------------------------------------------------------
class TheManagerFactory
{
public:
// Non-static, non-const to allow polymorphism-abuse
virtual CSomeManager *CreateSomeManager() { return new CSomeManager(); }
virtual COtherManager *CreateOtherManager() { return new COtherManager(); }
};
//--------------------------------------------------------------------------------
class CDerivedFromSomeManager : public CSomeManager
{
public:
virtual const char * ShoutOut() { return "CDerivedFromSomeManager";}
};
//--------------------------------------------------------------------------------
class TheCustomManagerFactory : public TheManagerFactory
{
public:
virtual CDerivedFromSomeManager *CreateSomeManager() { return new CDerivedFromSomeManager(); }
};
//--------------------------------------------------------------------------------
class CMetaManager
{
public:
CMetaManager(TheManagerFactory *ip_factory)
: mp_some_manager(ip_factory->CreateSomeManager()),
mp_other_manager(ip_factory->CreateOtherManager())
{}
CSomeManager *GetSomeManager() { return mp_some_manager; }
COtherManager *GetOtherManager() { return mp_other_manager; }
private:
CSomeManager *mp_some_manager;
COtherManager *mp_other_manager;
};
//--------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
TheManagerFactory standard_factory;
TheCustomManagerFactory custom_factory;
CMetaManager meta_manager_1(&standard_factory);
CMetaManager meta_manager_2(&custom_factory);
std::cout << meta_manager_1.GetSomeManager()->ShoutOut() << "\n";
std::cout << meta_manager_2.GetSomeManager()->ShoutOut() << "\n";
return 0;
}
class SomeOtherManager;
class SomeManagerClass {
public:
SomeManagerClass(SomeOtherManager*);
virtual void someMethod1();
virtual void someMethod2();
};
class TheBaseManager {
public:
//
};
template <class ManagerClassOne, class ManagerClassOther>
class SpecialManager : public TheBaseManager {
public:
virtual ManagerClassOne* someManagerClass() const;
virtual ManagerClassOther* someOtherManager() const;
};
TheBaseManager* ourManager = new SpecialManager<SomeManagerClass,SomeOtherManager>;
class Manager
{
public:
virtual void doSomething() = 0;
virtual int doSomethingElse() = 0;
}
extern "C" {
Manager* newManager();
void deleteManager(Manager*);
}
#include "Manager.h"
class PluginManager : public Manager
{
public:
PluginManager();
virtual ~PluginManager();
public:
virtual void doSomething();
virtual int doSomethingElse();
}
#include "PluginManager.h"
Manager* newManager()
{
return new PluginManager();
}
void deleteManager(Manager* pManager)
{
delete pManager;
}
PluginManager::PluginManager()
{
// ...
}
PluginManager::~PluginManager()
{
// ...
}
void PluginManager::doSomething()
{
// ...
}
int PluginManager::doSomethingElse()
{
// ...
}
class factory
{
public:
virtual SomeManagerClass* create() = 0;
};
class plugin1_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin1(); }
};
std::map<string, factory*> factory_map;
...
factory_map["plugin1"] = new plugin1_factory();
SomeManagerClass* obj = factory_map[plugin_name]->create();
template <class plugin_type>
class plugin_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin_type(); }
};
factory_map["plugin1"] = new plugin_factory<plugin1>();
class IFrameWork {
public:
virtual ~IFrameWork() {}
virtual void RegisterInterface( const char*, void* ) = 0;
virtual void* GetInterface( const char* name ) = 0;
};
class IPlugIn {
public:
virtual ~IPlugIn() {}
virtual void BindInterfaces( IFrameWork* frameWork ) {};
virtual void Start() {};
virtual void Stop() {};
};
struct SamplePlugin :public IPlugIn {
ILogger* logger;
Component1 component1;
WebServer webServer;
public:
SamplePlugin( IFrameWork* frameWork )
:logger( (ILogger*)frameWork->GetInterface( "ILogger" ) ), //assumes the 'System' plugin exposes this
component1(),
webServer( component1 )
{
logger->Log( "MyPlugin Ctor()" );
frameWork->RegisterInterface( "ICustomerManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IVendorManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IAccountingManager", dynamic_cast( &webServer ) );
}
virtual void BindInterfaces( IFrameWork* frameWork ) {
logger->Log( "MyPlugin BindInterfaces()" );
IProductManager* productManager( static_cast( frameWork->GetInterface( "IProductManager" ) ) );
IShippingManager* shippingManager( static_cast( frameWork->GetInterface( "IShippingManager" ) ) );
component1.BindInterfaces( logger, productManager );
webServer.BindInterfaces( logger, productManager, shippingManager );
}
virtual void Start() {
logger->Log( "MyPlugin Start()" );
webServer.Start();
}
virtual void Stop() {
logger->Log( "MyPlugin Stop()" );
webServer.Stop();
}
};
class FrameWork :public IFrameWork {
vector plugIns;
map interfaces;
public:
virtual void RegisterInterface( const char* name, void* itfc ) {
interfaces[ name ] = itfc;
}
virtual void* GetInterface( const char* name ) {
return interfaces[ name ];
}
FrameWork() {
//Only interfaces in 'SystemPlugin' can be used by all methods of the other plugins
plugIns.push_back( new SystemPlugin( this ) );
plugIns.push_back( new SamplePlugin( this ) );
//add other plugIns here
for_each( plugIns.begin(), plugIns.end(), bind2nd( mem_fun( &IPlugIn::BindInterfaces ), this ) );
for_each( plugIns.begin(), plugIns.end(), mem_fun( &IPlugIn::Start ) );
}
~FrameWork() {
for_each( plugIns.rbegin(), plugIns.rend(), mem_fun( &IPlugIn::Stop ) );
for_each( plugIns.rbegin(), plugIns.rend(), Delete() );
}
};
#include "stdafx.h"
#include <map>
#include <string>
class BaseClass
{
public:
virtual ~BaseClass() { }
virtual void Test() = 0;
};
class DerivedClass1 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class DerivedClass2 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class IFactory
{
public:
virtual BaseClass* CreateNew() const = 0;
};
template <typename T>
class Factory : public IFactory
{
public:
T* CreateNew() const { return new T(); }
};
class FactorySystem
{
private:
typedef std::map<std::wstring, IFactory*> FactoryMap;
FactoryMap m_factories;
public:
~FactorySystem()
{
FactoryMap::const_iterator map_item = m_factories.begin();
for (; map_item != m_factories.end(); ++map_item) delete map_item->second;
m_factories.clear();
}
template <typename T>
void AddFactory(const std::wstring& name)
{
delete m_factories[name]; // Delete previous one, if it exists.
m_factories[name] = new Factory<T>();
}
BaseClass* CreateNew(const std::wstring& name) const
{
FactoryMap::const_iterator found = m_factories.find(name);
if (found != m_factories.end())
return found->second->CreateNew();
else
return NULL; // or throw an exception, depending on how you want to handle it.
}
};
int _tmain(int argc, _TCHAR* argv[])
{
FactorySystem system;
system.AddFactory<DerivedClass1>(L"derived1");
system.AddFactory<DerivedClass2>(L"derived2");
BaseClass* b1 = system.CreateNew(L"derived1");
b1->Test();
delete b1;
BaseClass* b2 = system.CreateNew(L"derived2");
b2->Test();
delete b2;
return 0;
}
class ManagerFactory
{
public:
template <typename T> static BaseManager * getManager() { return new T();}
};
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
#include <map>
#include <string>
class BaseManager
{
public:
virtual void doSomething() = 0;
};
class DerivedManager1 : public BaseManager
{
public:
virtual void doSomething() {};
};
class DerivedManager2 : public BaseManager
{
public:
virtual void doSomething() {};
};
class ManagerFactory
{
public:
typedef BaseManager * (*GetFunction)();
typedef std::map<std::wstring, GetFunction> ManagerFunctionMap;
private:
static ManagerFunctionMap _managers;
public:
template <typename T> static BaseManager * getManager() { return new T();}
template <typename T> static void registerManager(const std::wstring& name)
{
_managers[name] = ManagerFactory::template getManager<T>;
}
static BaseManager * getManagerByName(const std::wstring& name)
{
if(_managers.count(name))
{
return _managers[name]();
}
return NULL;
}
};
// the static map needs to be initialized outside the class
ManagerFactory::ManagerFunctionMap ManagerFactory::_managers;
int _tmain(int argc, _TCHAR* argv[])
{
// you can get with the templated function
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
manager1->doSomething();
// or by registering with a string
ManagerFactory::template registerManager<DerivedManager1>(L"Derived1");
ManagerFactory::template registerManager<DerivedManager2>(L"Derived2");
// and getting them
BaseManager * manager2 = ManagerFactory::getManagerByName(L"Derived2");
manager2->doSomething();
BaseManager * manager3 = ManagerFactory::getManagerByName(L"Derived1");
manager3->doSomething();
return 0;
}