首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单例抽象工厂模式

单例抽象工厂模式
EN

Stack Overflow用户
提问于 2012-09-30 20:56:11
回答 3查看 5.9K关注 0票数 4

我想实现一个抽象工厂模式,但也想成为一个单例。

代码语言:javascript
复制
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
    }
    ;
};

有没有人能帮我写一些抽象工厂单例的示例代码?

提前谢谢。

EN

回答 3

Stack Overflow用户

发布于 2012-10-01 02:08:05

我设法想出了更优雅的解决方案(到目前为止还没有错误检查)。请让我知道你的想法

代码语言:javascript
复制
#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();
}
票数 8
EN

Stack Overflow用户

发布于 2012-09-30 22:14:42

如果你需要一个真正的动态抽象工厂,你需要在运行时以某种方式设置它。您可以通过让一个函数选择所需的工厂来实现这一点,该函数只设置实际的单例。在实际的应用程序中,您可能有某种注册函数,您可以在其中注册函数,以获取工厂的实例(工厂工厂函数)。在下面的示例中,我使用了一个简单的设置,其中可用工厂在编译时是已知的。

代码语言:javascript
复制
#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 + "'");
    }
}
票数 1
EN

Stack Overflow用户

发布于 2012-09-30 21:06:05

代码语言:javascript
复制
namespace WindowFactory {
      Scrollbar* createScrollbar() {
        #ifdef TARGET_OS_MAC 
         ...
        #elif __linux__ 
         ...
        #endif
      }
};

我也会这么做的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12661405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档