I would like to implement a Abstract Factory pattern but also would like to be a singleton.
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
    }
    ;
};
Can someone help me with some sample code of making this Abstract Factory Singleton ?
Thanks in advance.
I managed to come up with more elegant solution ( No error checking as of now ). Kindly let me know your thoughts
#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();
}
                        If you need an actually dynamic abstract factory, you'd need to somehow set it up at run-time. You can do this by having a function selecting the desired factory with a suitable function which just sets up the actual singleton. In a real application you would probably have some sort of registration function where you can register functions getting an instance for the factory (factory factory functions). In the example below I used a simple set up where the available factories are known at compile time.
#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 + "'");
    }
}
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With