Design Patterns
Материал из Wiki.crossplatform.ru
Версия от 13:25, 10 мая 2013; ViGOur (Обсуждение | вклад)
Порождающие паттерны проектирования
Абстрактная фабрика (Abstract Factory, Factory), др. название Инструментарий (Kit)
#include <iostream> class CLanguage { public: virtual void generate() = 0; }; class CPytnon : public CLanguage { public: void generate() { std::cout << "Generate python code" << std::endl; } }; class CJava : public CLanguage { public: void generate() { std::cout << "Generate java code" << std::endl; } }; class CLangFactory { public: virtual CLanguage* createLanguage() = 0; }; class CPythonFactory : public CLangFactory { public: CLanguage* createLanguage(){ return new CPytnon(); } }; class CJavaFactory : public CLangFactory { public: CLanguage* createLanguage() { return new CJava(); } }; class CCodeGenerator { public: CCodeGenerator(CLangFactory* factory) { CLanguage *pLang = factory->createLanguage(); pLang->generate(); delete pLang; delete factory; } }; CLangFactory* createCodeFactory() { int nLang = -1; std::cout << "Enter Language type (0: Python, 1: Java): "; std::cin >> nLang; switch( nLang ) { case 0: return new CPythonFactory(); case 1: return new CJavaFactory(); default: std::cout << "Error choice language..." << std::endl; return 0; } } int main() { CLangFactory *plf = createCodeFactory(); if( plf ) CCodeGenerator cg( plf ); return 0; }
Одиночка (Singleton)
Статический
class CSingleton { private: static CSingleton m_singleton; private: CSingleton() {} ~CSingleton() {} CSingleton(const CSingleton &) {} CSingleton & operator=(const CSingleton &) { return *this; } public: static CSingleton *instance() { return &m_singleton; } }; CSingleton CSingleton::m_singleton; int main(int , char **) { CSingleton *p = CSingleton::instance(); // ... return 0; }
Динамический
class CSingleton { private: static CSingleton *m_pSingleton; static int m_nCounter; private: CSingleton() {} ~CSingleton() {} CSingleton(const CSingleton &) {} CSingleton & operator=(const CSingleton &) { return *this; } public: static CSingleton *instance() { if( m_nCounter == 0 ) { m_pSingleton = new CSingleton(); } m_nCounter++; return m_pSingleton; } static CSingleton *freeInstance() { if( m_nCounter > 0 ) { m_nCounter--; if( m_nCounter == 0 ) { delete m_pSingleton; m_pSingleton = 0; } } } }; CSingleton *CSingleton::m_pSingleton = 0; int CSingleton::m_nCounter = 0; int main(int , char **) { CSingleton *p = CSingleton::instance(); return 0; }
Шаблонный
class CClass { public: virtual ~CClass(){ } }; template <class T> class CTypedSingleton; template<class T> class CTypedWrapper : public T, private CTypedSingleton<T> { public: void operator delete(void *p) { CTypedSingleton<T>::free(); } }; template <class T> class CTypedSingleton { static T* m_self; static int m_refcount; protected: CTypedSingleton(){} CTypedSingleton(const CTypedSingleton&){} virtual ~CTypedSingleton(){ m_self = 0; } CTypedSingleton &operator=(const CTypedSingleton&){} public: static T *init() { if(!m_self) m_self = new CTypedWrapper<T>; m_refcount++; return m_self; } static void free() { if( m_refcount > 0) { --m_refcount; if( m_refcount == 0) { delete m_self; m_self = 0; } } } }; template <class T> T *CTypedSingleton<T>::m_self = 0; template <class T> int CTypedSingleton<T>::m_refcount = 0; int main(int , char **) { CClass *p = CTypedSingleton<CClass>::init(); delete p; return 0; }
Многопоточный (double-checked locking)
#include <cstdlib> #include <boost/thread/once.hpp> template <class T> class Singleton { public: static T& Instance(); private: Singleton() {}; Singleton(const Singleton&); Singleton& operator=(const Singleton&); virtual ~Singleton() {}; static void Init() { boost::call_once(m_init, &Singleton<T>::InitImpl); } static void InitImpl() { m_me = new T; atexit(&Singleton<T>::FreeInstance); } static void FreeInstance() { boost::call_once(m_done, &Singleton<T>::FreeImpl); }; static void FreeImpl() { delete m_me; m_me = NULL; } friend int atexit(void (__cdecl *func)(void)); private: static T* volatile m_me; static boost::once_flag m_init, m_done; }; template <class T> T* Singleton<T>::m_me = NULL; template <class T> boost::once_flag Singleton<T>::m_init = BOOST_ONCE_INIT; template <class T> boost::once_flag Singleton<T>::m_done = BOOST_ONCE_INIT; template <class T> T& Singleton<T>::Instance() { Init(); return (*m_me); }
Прототип (Prototype)
#include <iostream> // Прототип class CPrototype { public: virtual CPrototype* clone() const = 0; }; // Прототип сайта class CSitePrototype : public CPrototype { private: int m_nPages; public: CSitePrototype(int nPages) : m_nPages( nPages ){} CSitePrototype(const CSitePrototype &r) : m_nPages( r.m_nPages ){} virtual CSitePrototype* clone() const { return new CSitePrototype( *this ); } void setPages(int nPages) { m_nPages = nPages; } int getPages() const { return m_nPages; } void printPages() const { std::cout << "Pages: " << m_nPages << std::endl; } }; // Клиентская сторона void clientSide() { CPrototype *pPrototype = new CSitePrototype( 256 ); for (int n = 0; n < 10; n++) { CSitePrototype *pSite = static_cast<CSitePrototype*>( pPrototype->clone() ); pSite->setPages( pSite->getPages() * n ); pSite->printPages(); delete pSite; } delete pPrototype; pPrototype = 0; } int main() { clientSide(); return 0; }
Создатель экземпляров класса (Creator)
Строитель (Builder)
#include <string> #include <iostream> class COs { private: int m_nType; int m_nCore; std::string m_szName; public: void setType( int nType ) { m_nType = nType; } void setCore( int nCore ) { m_nCore = nCore; } void setName( std::string szName ) { m_szName = szName; } void print() { std::cout << "Os type: " << m_nType << " core: " << m_nCore << " name: " << m_szName << std::endl; } }; class COsBuilder { protected: COs *m_pOs; public: void createNewOs() { m_pOs = new COs(); } COs *os() { return m_pOs; } virtual void setOsType() = 0; virtual void setOsCore() = 0; virtual void setOsName() = 0; }; class CLinuxBuilder : public COsBuilder { public: void setOsType() { m_pOs->setType( 0 ); } void setOsCore() { m_pOs->setCore( 11111 ); } void setOsName() { m_pOs->setName( "Red hat" ); } }; class CWindowsBuilder : public COsBuilder { public: void setOsType() { m_pOs->setType( 1 ); } void setOsCore() { m_pOs->setCore( 22222 ); } void setOsName() { m_pOs->setName( "Windows 8" ); } }; class CSysAdmin { private: COsBuilder *m_pBuilder; public: CSysAdmin(): m_pBuilder(0){} virtual ~CSysAdmin() { freeBuilder(); } void freeBuilder() { if( m_pBuilder ) { delete m_pBuilder; m_pBuilder = 0; } } void setBuilder(COsBuilder* pBuilder) { freeBuilder(); m_pBuilder = pBuilder; } void construct() { m_pBuilder->createNewOs(); m_pBuilder->setOsType(); m_pBuilder->setOsCore(); m_pBuilder->setOsName(); } void printOs(){ m_pBuilder->os()->print(); } }; int main() { CSysAdmin sys; sys.setBuilder(new CLinuxBuilder); sys.construct(); sys.printOs(); sys.setBuilder(new CWindowsBuilder); sys.construct(); sys.printOs(); }
Фабричный метод (Factory Method) или Виртуальный конструктор (Virtual Constructor)
#include <iostream> class CDocument { public: virtual void save() = 0; }; class CWord: public CDocument { public: void save() { std::cout << "Save word document." << std::endl; } }; class CExcel: public CDocument { public: void save() { std::cout << "Save excel document." << std::endl; } }; class CApplication { int m_nTypeDocument; public: CApplication( int nTypeDocument ):m_nTypeDocument(nTypeDocument){} void setTypeDocument(int nTypeDocument ){ m_nTypeDocument = nTypeDocument; } void saveFile() { CDocument *pDoc = getTypeDocument(); if( pDoc ) pDoc->save(); } CDocument *getTypeDocument() { switch( m_nTypeDocument ) { case 0: return new CWord(); case 1: return new CExcel(); } return 0; } }; int main() { CApplication app( 0 ); app.saveFile(); // Word app.setTypeDocument( 1 ); app.saveFile(); // Excel return 0; }