Singleton Abstract Factory Template

I would like to implement the Abstract Factory pattern, but would also like to be single.

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 to create this abstract Factory Singleton?

Thanks in advance.

+4
source share
3 answers

I managed to come up with a more elegant solution (there is currently no error checking). Please 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(); } 
+6
source

If you need a virtually dynamic abstract factory, you need to somehow configure it at runtime. You can do this by executing a function, selecting the desired factory with a suitable function that just sets the actual singleton. In a real application, you will probably have some kind of registration function where you can register functions receiving an instance for the factory (factory factory) functions. In the example below, I used a simple setup where available plants 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 + "'"); } } 
+1
source
 namespace WindowFactory { Scrollbar* createScrollbar() { #ifdef TARGET_OS_MAC ... #elif __linux__ ... #endif } }; 

How I would do it.

0
source

Source: https://habr.com/ru/post/1437036/


All Articles