Design Pattern(C++)——Abstract Factory
Introduction
我使用实例来说明各个设计模式,因为理论已经讲得太多了,现在我来体现理论对实践的指导作用。在我设计一个插件结构的时候,我需要考虑可移植的问题。在不同的平台中管理插件的控制类具有相同的接口,但具有不同的具体行为,比如有for Win32的PluginManager,有for Linux的PluginManager,等等。这些PluginManager都遵循相同的接口,但有各自的实现。为了对使用者屏蔽这些内部的细节,不和具体的某个PluginManager耦合起来,我使用了一个工厂来负责创建它们的实例。类似的,工厂还创建其它的对象,如PluginRegistry。我可以在工厂中创建某个具体的PluginManager,某个工厂创建某个具体的PluginManager,而这些工厂具有相同的接口ObjectFactory。另外,我对ObjectFactory使用了单例模式。这里的单例模式没有使用静态成员,而只是在函数内部使用了一个局部静态变量,这是利用了C++的特性。
Class & Description

|
Class |
Description |
|
ObjectFactory |
一个抽象工厂,负责创建PluginManager等对象,同时使用了单例模式getInstance函数默认返回Win32ObjectFactory对象 |
|
PluginManager |
一种产品,这里是插件管理类的接口 |
|
Win32ObjectFactory |
派生自PluginManager ,Win32平台下ObjectFactory的实现,否则创建对应的PluginManager对象 |
|
Win32PluginManager |
派生自PluginManager ,Win32平台下PluginManager的实现 |
|
PluginRegistry |
一种产品 |
|
…… |
|
C++ Implementation
Environment
Windows XP Professional,Visual C++2005
ObjectFactory
默认是创建Win32PluginManager,在实际开发中先判断平台类型,然后创建相应的PluginManager对象。
|
//ObjectFactory.h #pragma once class PluginManager; class PluginRegistry; class PluginLifecycleHandler; class ObjectFactory { protected: ObjectFactory(void); public: virtual ~ObjectFactory(void); virtual PluginManager* createPluginManager() = 0; virtual PluginRegistry* createPluginRegistry()=0; virtual PluginLifecycleHandler* createPluginLifecycleHandler()=0; public: static ObjectFactory* getInstance(); }; // ObjectFactory.cpp #include "StdAfx.h" #include "PluginManager.h" #include "PluginRegistry.h" #include "PluginLifecycleHandler.h" #include "ObjectFactory.h" #include "Win32ObjectFactory.h" ObjectFactory::ObjectFactory(void) { } ObjectFactory::~ObjectFactory(void) { } ObjectFactory* ObjectFactory::getInstance() { static ObjectFactory* instance = NULL; if ( instance == NULL ) { instance = new Win32ObjectFactory(); } return instance; } |
PluginManager
|
//PluginManager.h #pragma once class PluginManager { public: PluginManager(void); public: ~PluginManager(void); }; //PluginManager.cpp #include "PluginManager.h" PluginManager::PluginManager(void) { } PluginManager::~PluginManager(void) { } |
Win32ObjectFactory
|
//Win32ObjectFactory.h #pragma once class ObjectFactory; class PluginManager; class PluginRegistry; class PluginLifecycleHandler; class Win32ObjectFactory: public ObjectFactory { public: Win32ObjectFactory(void); public: ~Win32ObjectFactory(void); public: PluginManager* createPluginManager(); PluginRegistry* createPluginRegistry(); PluginLifecycleHandler* createPluginLifecycleHandler(); }; //Win32ObjectFactory.cpp #include "StdAfx.h" #include "ObjectFactory.h" #include "PluginManager.h" #include "PluginRegistry.h" #include "PluginLifecycleHandler.h" #include "Win32ObjectFactory.h" #include "Win32PluginManager.h" #include "PluginRegistryImpl.h" #include "PluginLifecycleHandlerImpl.h" Win32ObjectFactory::Win32ObjectFactory(void) { } Win32ObjectFactory::~Win32ObjectFactory(void) { } PluginManager* Win32ObjectFactory::createPluginManager() { return (PluginManager*)(new Win32PluginManager()); } PluginRegistry* Win32ObjectFactory::createPluginRegistry() { return (PluginRegistry*)(new PluginRegistryImpl()); } PluginLifecycleHandler* Win32ObjectFactory::createPluginLifecycleHandler() { return (PluginLifecycleHandler*)(new PluginLifecycleHandlerImpl()); } |
Win32PluginManager
|
// Win32PluginManager.h #pragma once class PluginManager; class Win32PluginManager:public PluginManager { public: Win32PluginManager(void); public: ~Win32PluginManager(void); }; // Win32PluginManager.cpp #include "PluginManager.h" #include "Win32PluginManager.h" Win32PluginManager::Win32PluginManager(void) { } Win32PluginManager::~Win32PluginManager(void) { } |
How to Use
|
#include "stdafx.h" #include "ObjectFactory.h" #include "PluginManager.h" #include "PluginRegistry.h" #include "PluginLifecycleHandler.h" int _tmain(int argc, _TCHAR* argv[]) { ObjectFactory* factory = ObjectFactory::getInstance(); PluginManager* manager = factory->createPluginManager(); PluginRegistry* registry = factory->createPluginRegistry(); PluginLifecycleHandler* handler = factory->createPluginLifecycleHandler(); //do something... return 0; } |
Postscript
抽象工厂是在实际应用中使用得最多的一个模式之一,它通常和单例模式(Singleton)结合使用,让工厂只构建一次——特别是当构建工厂需要花费比较大的代价的时候。另外,一个工厂也可以创建多个不同接口的对象——曾经遇到有人认为一个工厂只能创建一个接口的对象。如果添加了新类型的对象需要由工厂来创建,则必须修改工厂的接口——但这种情况并不是很多见。另外,还可以使用参数化的工厂方法,比如给createPluginManager方法加一个参数,根据参数来创建对象,但这个方法的实现中会写一些if或者switch-case语句,而这是僵化的语句;灵活的做法莫过于根据class名来创建对象——c++也能比较容易得做到,就是需要做更多的工作。
为了减少编译文件上的依赖,我避免在.h文件中include别的.h文件,而是在.cpp文件中include必要的.h文件。这是《Effective C++》中指出的方法,也是平常C++开发中的做法。
浙公网安备 33010602011771号