我想实现一个抽象工厂模式,但也希望成为一个单例。
class WindowFactory {
protected:
virtual Scrollbar* createScrollbar() = 0;
};
class MacWindowFactory: public WindowFactory {
virtual Scrollbar* createScrollbar() {
//return a instance
}
;
};
class LinuxWindowFactory: public WindowFactory {
virtual ScrollBar* createScrollbar() {
//return a instance
}
;
};
有人可以帮我提供一些制作这个抽象工厂单身的示例代码吗?
提前致谢。
答案 0 :(得分:8)
我设法提出了更优雅的解决方案(截至目前没有错误检查)。请让我知道你的想法
#include<iostream>
#include<map>
class AbstractFactory
{
private:
typedef std::map< std::string, AbstractFactory* > ClientMap;
static ClientMap s_clientMap;
public:
void virtual createScrollbar() = 0;
void virtual createWindow() = 0;
static AbstractFactory* createInstance( std::string client );
protected:
void Register( std::string, AbstractFactory* );
};
AbstractFactory::ClientMap AbstractFactory::s_clientMap;
class LinuxFactory: public AbstractFactory
{
public:
void createScrollbar()
{
std::cout<<"Scrollbar for Linux"<<std::endl;
}
void createWindow()
{
std::cout<<"WIndow for Linux"<<std::endl;
}
private:
LinuxFactory()
{
Register( "Linux", this );
}
LinuxFactory( const LinuxFactory& );
static LinuxFactory s_LinuxFactory;
};
LinuxFactory LinuxFactory::s_LinuxFactory;
class MacFactory: public AbstractFactory
{
public:
void createScrollbar()
{
std::cout<<"Scrollbar for Mac"<<std::endl;
}
void createWindow()
{
std::cout<<"WIndow for Mac"<<std::endl;
}
private:
MacFactory()
{
Register( "Mac", this );
}
MacFactory( const MacFactory& );
static MacFactory s_MacFactory;
};
MacFactory MacFactory::s_MacFactory;
void AbstractFactory::Register( std::string clientName, AbstractFactory* factory )
{
s_clientMap.insert( ClientMap::value_type( clientName, factory ) );
}
AbstractFactory* AbstractFactory::createInstance( std::string client )
{
return s_clientMap.find( client )->second;
}
int main()
{
AbstractFactory *factory = AbstractFactory::createInstance( "Linux" );
factory->createScrollbar();
factory->createWindow();
}
答案 1 :(得分:1)
如果你需要一个实际动态的抽象工厂,你需要以某种方式在运行时设置它。您可以通过选择具有合适功能的所需工厂的功能来设置实际单例。在实际的应用程序中,您可能会有某种注册功能,您可以在其中注册获取工厂实例的功能(工厂工厂功能)。在下面的例子中,我使用了一个简单的设置,在编译时可以知道可用的工厂。
#include <memory>
#include <stdexcept>
#include <string>
class Scrollbar;
class WindowFactory {
public:
static void setFactory(std::string const&);
static Scrollbar* createScrollbar();
virtual ~WindowFactory() {}
private:
virtual Scrollbar* doCreateScrollbar() = 0;
};
class MacWindowFactory
: public WindowFactory {
friend void WindowFactory::setFactory(std::string const&);
virtual Scrollbar* doCreateScrollbar() {
return 0;
}
};
class LinuxWindowFactory
: public WindowFactory {
friend void WindowFactory::setFactory(std::string const&);
virtual Scrollbar* doCreateScrollbar() {
return 0;
}
};
// in WindowFactory.cpp
static std::auto_ptr<WindowFactory>& getPointer()
{
static std::auto_ptr<WindowFactory> pointer;
return pointer;
}
Scrollbar* WindowFactory::createScrollbar()
{
return getPointer().get()
? getPointer()->doCreateScrollbar()
: throw std::runtime_error("WindowFactory not set");
}
void WindowFactory::setFactory(std::string const& what)
{
if (what == "Mac") {
getPointer() = std::auto_ptr<WindowFactory>(new MacWindowFactory());
}
else if (what == "Linux") {
getPointer() = std::auto_ptr<WindowFactory>(new LinuxWindowFactory());
}
else {
throw std::runtime_error("unknown factory: '" + what + "'");
}
}
答案 2 :(得分:0)
namespace WindowFactory {
Scrollbar* createScrollbar() {
#ifdef TARGET_OS_MAC
...
#elif __linux__
...
#endif
}
};
我就是这样做的。