Design Patterns
Материал из Wiki.crossplatform.ru
(Различия между версиями)
ViGOur (Обсуждение | вклад) (→Абстрактная фабрика (Abstract Factory, Factory), др. название Инструментарий (Kit)) |
ViGOur (Обсуждение | вклад) (→Фабричный метод (Factory Method) или Виртуальный конструктор (Virtual Constructor)) |
||
Строка 389: | Строка 389: | ||
== Фабричный метод (Factory Method) или Виртуальный конструктор (Virtual Constructor) == | == Фабричный метод (Factory Method) или Виртуальный конструктор (Virtual Constructor) == | ||
+ | <source lang="cpp"> | ||
+ | #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; | ||
+ | }</source> | ||
= Структурные паттерны проектирования классов/обьектов = | = Структурные паттерны проектирования классов/обьектов = |
Версия 13:09, 16 апреля 2013
Порождающие паттерны проектирования
Абстрактная фабрика (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 CCode { private: std::string m_szCode; public: void build(const std::string &rCode) { m_szCode = rCode; } void print() const { std::cout << "Code: " << m_szCode << std::endl; } }; // Abstract Builder class CCodeBuilder { protected: CCode m_code; public: const CCode& code() { return m_code; } virtual void buildCode() = 0; }; class CPythonBuilder : public CCodeBuilder { public: void buildCode() { m_code.build("python code"); } }; class CJavaBuilder : public CCodeBuilder { public: void buildCode() { m_code.build("java code"); } }; class CDeveloper { private: CCodeBuilder *m_pCodeBuilder; public: CDeveloper(): m_pCodeBuilder(0){} virtual ~CDeveloper() { freeCodeBuilder(); } void freeCodeBuilder() { if( m_pCodeBuilder ) { delete m_pCodeBuilder; m_pCodeBuilder = 0; } } void setCodeBuilder(CCodeBuilder* pCodeBuilder) { freeCodeBuilder(); m_pCodeBuilder = pCodeBuilder; } const CCode& getCode() { return m_pCodeBuilder->code(); } void constructCode() { m_pCodeBuilder->buildCode(); } }; int main() { CDeveloper dev; dev.setCodeBuilder(new CPythonBuilder); dev.constructCode(); CCode python = dev.getCode(); python.print(); dev.setCodeBuilder(new CJavaBuilder); dev.constructCode(); CCode java = dev.getCode(); java.print(); }
Фабричный метод (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; }