Текущая версия |
Ваш текст |
Строка 24: |
Строка 24: |
| { | | { |
| public: | | public: |
- | virtual CLanguage* createLanguage() = 0; | + | virtual CLanguage* generateCode() = 0; |
| }; | | }; |
| | | |
Строка 30: |
Строка 30: |
| { | | { |
| public: | | public: |
- | CLanguage* createLanguage(){ return new CPytnon(); } | + | CLanguage* generateCode(){ return new CPytnon(); } |
| }; | | }; |
| | | |
Строка 36: |
Строка 36: |
| { | | { |
| public: | | public: |
- | CLanguage* createLanguage() { return new CJava(); } | + | CLanguage* generateCode() { return new CJava(); } |
| }; | | }; |
| | | |
Строка 44: |
Строка 44: |
| CCodeGenerator(CLangFactory* factory) | | CCodeGenerator(CLangFactory* factory) |
| { | | { |
- | CLanguage *pLang = factory->createLanguage(); | + | CLanguage *pLang = factory->generateCode(); |
| pLang->generate(); | | pLang->generate(); |
| delete pLang; | | delete pLang; |
Строка 261: |
Строка 261: |
| | | |
| == Прототип (Prototype) == | | == Прототип (Prototype) == |
- | <source lang="cpp">#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;
| |
- | }</source>
| |
- |
| |
| == Создатель экземпляров класса (Creator) == | | == Создатель экземпляров класса (Creator) == |
- | <source lang="cpp">template <typename TItem>
| |
- | class CDataStorage
| |
- | {
| |
- | private:
| |
- | std::vector<TItem*> m_items;
| |
- |
| |
- | public:
| |
- | CDataStorage () {};
| |
- | ~CDataStorage ()
| |
- | {
| |
- | for (auto it = m_items.begin (); it != m_items.end(); ++it)
| |
- | delete *it;
| |
- | }
| |
- |
| |
- | std::size_t createItem ()
| |
- | {
| |
- | std::size_t item_index = m_items.size ();
| |
- | m_items.push_back (new TItem());
| |
- | return item_index;
| |
- | }
| |
- |
| |
- | std::size_t size () const { return m_items.size ();}
| |
- | TItem & itemAt (std::size_t index) { return *m_items[index];}
| |
- | const TItem & itemAt (std::size_t index) const { return *m_items[index];}
| |
- | };
| |
- |
| |
- | int main(int argc, char* argv[])
| |
- | {
| |
- | CDataStorage<int> data;
| |
- | data.createItem ();
| |
- | data.createItem ();
| |
- | int &item1 = data.itemAt (0);
| |
- | item1 = 42;
| |
- | std::cout << data.itemAt (0);
| |
- | }</source>
| |
- |
| |
| == Строитель (Builder) == | | == Строитель (Builder) == |
- | <source lang="cpp">#include <string> | + | <source lang="cpp"> |
| + | #include <string> |
| #include <iostream> | | #include <iostream> |
| | | |
- | class COs | + | class CCode |
| { | | { |
| private: | | private: |
- | int m_nType;
| + | std::string m_szCode; |
- | int m_nCore;
| + | |
- | std::string m_szName; | + | |
| | | |
| public: | | public: |
- | void setType( int nType ) { m_nType = nType; } | + | void build(const std::string &rCode) { m_szCode = rCode; } |
- | void setCore( int nCore ) { m_nCore = nCore; }
| + | void print() const { std::cout << "Code: " << m_szCode << std::endl; } |
- | 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 | + | // Abstract Builder |
| + | class CCodeBuilder |
| { | | { |
| protected: | | protected: |
- | COs *m_pOs; | + | CCode m_code; |
| | | |
| public: | | public: |
- | void createNewOs() { m_pOs = new COs(); } | + | const CCode& code() { return m_code; } |
- | COs *os() { return m_pOs; }
| + | |
| | | |
- | virtual void setOsType() = 0; | + | virtual void buildCode() = 0; |
- | virtual void setOsCore() = 0;
| + | |
- | virtual void setOsName() = 0;
| + | |
| }; | | }; |
| | | |
- | class CLinuxBuilder : public COsBuilder { | + | class CPythonBuilder : public CCodeBuilder { |
| public: | | public: |
- | void setOsType() { m_pOs->setType( 0 ); } | + | void buildCode() { m_code.build("cpp code"); } |
- | void setOsCore() { m_pOs->setCore( 11111 ); }
| + | |
- | void setOsName() { m_pOs->setName( "Red hat" ); }
| + | |
| }; | | }; |
| | | |
- | class CWindowsBuilder : public COsBuilder | + | class CJavaBuilder : public CCodeBuilder |
| { | | { |
| public: | | public: |
- | void setOsType() { m_pOs->setType( 1 ); } | + | void buildCode() { m_code.build("delphi code"); } |
- | void setOsCore() { m_pOs->setCore( 22222 ); }
| + | |
- | void setOsName() { m_pOs->setName( "Windows 8" ); }
| + | |
| }; | | }; |
| | | |
- | class CSysAdmin | + | class CDeveloper |
| { | | { |
| private: | | private: |
- | COsBuilder *m_pBuilder; | + | CCodeBuilder *m_pCodeBuilder; |
| | | |
| public: | | public: |
- | CSysAdmin(): m_pBuilder(0){} | + | CDeveloper(): m_pCodeBuilder(0){} |
- | virtual ~CSysAdmin() { freeBuilder(); } | + | virtual ~CDeveloper() { freeCodeBuilder(); } |
| | | |
- | void freeBuilder() | + | void freeCodeBuilder() |
| { | | { |
- | if( m_pBuilder ) | + | if( m_pCodeBuilder ) |
| { | | { |
- | delete m_pBuilder; | + | delete m_pCodeBuilder; |
- | m_pBuilder = 0; | + | m_pCodeBuilder = 0; |
| } | | } |
| } | | } |
- | void setBuilder(COsBuilder* pBuilder) | + | |
| + | void setCodeBuilder(CCodeBuilder* pCodeBuilder) |
| { | | { |
- | freeBuilder(); | + | freeCodeBuilder(); |
- | m_pBuilder = pBuilder; | + | m_pCodeBuilder = pCodeBuilder; |
| } | | } |
- | void construct() | + | const CCode& getCode() { return m_pCodeBuilder->code(); } |
- | {
| + | void constructCode() { m_pCodeBuilder->buildCode(); } |
- | m_pBuilder->createNewOs();
| + | |
- | m_pBuilder->setOsType();
| + | |
- | m_pBuilder->setOsCore();
| + | |
- | m_pBuilder->setOsName();
| + | |
- | }
| + | |
- | | + | |
- | void printOs(){ m_pBuilder->os()->print(); } | + | |
| }; | | }; |
| | | |
| int main() | | int main() |
| { | | { |
- | CSysAdmin sys; | + | CDeveloper dev; |
| | | |
- | sys.setBuilder(new CLinuxBuilder); | + | dev.setCodeBuilder(new CPythonBuilder); |
- | sys.construct(); | + | dev.constructCode(); |
- | sys.printOs(); | + | CCode python = dev.getCode(); |
| + | python.print(); |
| | | |
- | sys.setBuilder(new CWindowsBuilder); | + | dev.setCodeBuilder(new CJavaBuilder); |
- | sys.construct(); | + | dev.constructCode(); |
- | sys.printOs(); | + | CCode java = dev.getCode(); |
- | }
| + | java.print(); |
- | </source> | + | }</source> |
| | | |
| == Фабричный метод (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>
| |
| | | |
| = Структурные паттерны проектирования классов/обьектов = | | = Структурные паттерны проектирования классов/обьектов = |
| == Адаптер (Adapter) == | | == Адаптер (Adapter) == |
- | <source lang="cpp">class CDisplay {
| |
- | public:
| |
- | void drawMessage (int x, int y, const std::string &message)
| |
- | {
| |
- | std::cout << "Display at " << x << " " << y << ": " << message << std::endl;
| |
- | }
| |
- | int width () { return 200; }
| |
- | int height () { return 100; }
| |
- | };
| |
- |
| |
- | class CDisplayAdapter {
| |
- | private:
| |
- | CDisplay *m_pDisplay;
| |
- | public:
| |
- | CDisplayAdapter (CDisplay *display) { m_pDisplay = display;}
| |
- | void message (float x, float y, const std::string &message)
| |
- | {
| |
- | int display_x = x * m_pDisplay->width ();
| |
- | int display_y = y * m_pDisplay->height ();
| |
- | m_pDisplay->drawMessage (display_x, display_y, message);
| |
- | }
| |
- | };
| |
- |
| |
- | int main(int argc, char* argv[])
| |
- | {
| |
- | CDisplay *output = new CDisplay ();
| |
- | CDisplayAdapter display_adapter (output);
| |
- |
| |
- | display_adapter.message (0.5f, 0.5f, "I'm center!");
| |
- | }</source>
| |
- |
| |
| == Декоратор (Decorator) или Оболочка (Wrapper) == | | == Декоратор (Decorator) или Оболочка (Wrapper) == |
- | Предназначен для динамического расширения функциональности объекта (добавления дополнительного поведения).
| |
- | <source lang=cpp>
| |
- | #include <iostream>
| |
- |
| |
- | class CWidget
| |
- | {
| |
- | public:
| |
- | virtual void draw() = 0;
| |
- | };
| |
- |
| |
- | class CDialog : public CWidget
| |
- | {
| |
- | public:
| |
- | void draw(){ std::cout << "Draw CDialog" << std::endl; }
| |
- | };
| |
- |
| |
- | class CToolBar : public CWidget
| |
- | {
| |
- | CWidget *m_pWrap;
| |
- | public:
| |
- | CToolBar( CWidget *pWrap ): m_pWrap(pWrap){}
| |
- | void draw(){ std::cout << "Draw CToolBar" << std::endl; m_pWrap->draw(); }
| |
- | };
| |
- |
| |
- | class CStatusBar : public CWidget
| |
- | {
| |
- | CWidget *m_pWrap;
| |
- | public:
| |
- | CStatusBar( CWidget *pWrap ): m_pWrap(pWrap){}
| |
- | void draw(){ m_pWrap->draw(); std::cout << "Draw CStatusBar" << std::endl; }
| |
- | };
| |
- |
| |
- | int main( int argc, char **argv)
| |
- | {
| |
- | CWidget *pDlg = new CDialog(); // Диалог без тулбара и статусбара
| |
- | pDlg->draw();
| |
- |
| |
- | std::cout << std::endl;
| |
- |
| |
- | CWidget *pDlgT = new CToolBar( new CDialog() ); // Диалог c тулбаром и без статусбара
| |
- | pDlgT->draw();
| |
- |
| |
- | std::cout << std::endl;
| |
- |
| |
- | CWidget *pDlgTS = new CToolBar( new CStatusBar( new CDialog() ) ); // Диалог c тулбаром и c статусбаром
| |
- | pDlgTS->draw();
| |
- |
| |
- | return 0;
| |
- | }
| |
- | </source>
| |
- | где, CToolBar и CStatusBar являются декораторами.
| |
- |
| |
- | Результат:
| |
- | <source lang=bash>
| |
- | Draw CDialog
| |
- |
| |
- | Draw CToolBar
| |
- | Draw CDialog
| |
- |
| |
- | Draw CToolBar
| |
- | Draw CDialog
| |
- | Draw CStatusBar
| |
- | </source>
| |
- |
| |
| == Заместитель (Proxy) или Суррогат (Surrogate) == | | == Заместитель (Proxy) или Суррогат (Surrogate) == |
- | Контролирует доступ к другому объекту, перехватывая все вызовы.
| |
- | <source lang=cpp>
| |
- | #include <iostream>
| |
- | #include <string>
| |
- |
| |
- | class CImage
| |
- | {
| |
- | std::string m_szName;
| |
- | public:
| |
- | CImage(std::string szName):m_szName(szName){}
| |
- | void draw(){ std::cout << "Drawing image: " << m_szName << std::endl; }
| |
- | void printName()const { std::cout << "CImage::printName" << std::endl; }
| |
- | };
| |
- |
| |
- | class CProxyImage
| |
- | {
| |
- | CImage *m_pImage;
| |
- | std::string m_szName;
| |
- | public:
| |
- | CProxyImage( std::string szName): m_pImage(0), m_szName(szName){}
| |
- | void draw()
| |
- | {
| |
- | if( !m_pImage )
| |
- | m_pImage = new CImage(m_szName);
| |
- | m_pImage->draw();
| |
- | }
| |
- | void printName()const
| |
- | {
| |
- | if( m_pImage )
| |
- | {
| |
- | m_pImage->printName();
| |
- | return;
| |
- | }
| |
- | std::cout << "CProxyImage::printName" << std::endl;
| |
- | }
| |
- | };
| |
- |
| |
- | int main( int argc, char **argv)
| |
- | {
| |
- | CProxyImage image( "testImage.png" );
| |
- | image.printName();
| |
- | image.draw();
| |
- | image.printName();
| |
- |
| |
- | return 0;
| |
- | }</source>В роли прокси тут выступает CProxyImage, который пока не вызван метод рисования картинки обрабатывает все запросы.
| |
- |
| |
- | Результат:
| |
- | <source lang=bash>CProxyImage::printName
| |
- | Drawing image: testImage.png
| |
- | CImage::printName</source>
| |
- |
| |
| == Информационный эксперт (Information Expert) == | | == Информационный эксперт (Information Expert) == |
| == Компоновщик (Composite) == | | == Компоновщик (Composite) == |
- | <source lang="cpp">class CDrawable {
| |
- | public:
| |
- | CDrawable () {};
| |
- | virtual ~CDrawable () {};
| |
- |
| |
- | virtual void draw () = 0;
| |
- | };
| |
- |
| |
- | class CCircle : public CDrawable {
| |
- | public:
| |
- | virtual void draw () { std::cout << "I'm a circle!" << std::endl;}
| |
- | };
| |
- |
| |
- | class CRectangle : public CDrawable {
| |
- | public:
| |
- | virtual void draw () { std::cout << "I'm a rectangle!" << std::endl;}
| |
- | };
| |
- |
| |
- | class CDrawableGroup : public CDrawable {
| |
- | private:
| |
- | std::list<CDrawable*> m_children;
| |
- | public:
| |
- | CDrawableGroup () {};
| |
- | virtual ~CDrawableGroup ()
| |
- | {
| |
- | while (!m_children.empty ()) {
| |
- | delete m_children.back ();
| |
- | m_children.pop_back ();
| |
- | };
| |
- | };
| |
- |
| |
- | void addChild (CDrawable *drawable) { m_children.push_back (drawable); };
| |
- | void removeChild (CDrawable *drawable)
| |
- | {
| |
- | m_children.remove (drawable);
| |
- | delete drawable;
| |
- | };
| |
- |
| |
- | virtual void draw () {
| |
- | for (auto it = m_children.begin (); it != m_children.end (); ++it)
| |
- | (*it)->draw ();
| |
- | };
| |
- | };
| |
- |
| |
- | int main(int argc, char* argv[])
| |
- | {
| |
- | CDrawableGroup figures;
| |
- | figures.addChild (new CCircle ());
| |
- |
| |
- | CDrawableGroup *rect_group = new CDrawableGroup ();
| |
- | rect_group->addChild (new CRectangle ());
| |
- | rect_group->addChild (new CRectangle ());
| |
- | figures.addChild (rect_group);
| |
- | figures.draw ();
| |
- | }</source>
| |
- |
| |
| == Мост (Bridge), Handle (описатель) или Тело (Body) == | | == Мост (Bridge), Handle (описатель) или Тело (Body) == |
- | <source lang="cpp">
| |
- | #include <iostream>
| |
- |
| |
- | class CWindowImp
| |
- | {
| |
- | public:
| |
- | virtual void drawWindow() = 0;
| |
- | };
| |
- |
| |
- | class CLinuxWindow : public CWindowImp
| |
- | {
| |
- | void drawWindow() { std::cout << "Draw linux window" << std::endl; }
| |
- | };
| |
- |
| |
- | class CWinWindow : public CWindowImp
| |
- | {
| |
- | void drawWindow() { std::cout << "Draw Windows window" << std::endl; }
| |
- | };
| |
- |
| |
- | class CMacWindow : public CWindowImp
| |
- | {
| |
- | void drawWindow() { std::cout << "Draw Mac window" << std::endl; }
| |
- | };
| |
- |
| |
- | class CWindowFactory
| |
- | {
| |
- | public:
| |
- | enum TYPES
| |
- | {
| |
- | LINUX = 0,
| |
- | WINDOWS,
| |
- | MAC
| |
- | };
| |
- |
| |
- | // будем считать, что у нас фабрика синглтон и все нормально с освобождением памяти... :)
| |
- | static CWindowImp *getWindowImp( CWindowFactory::TYPES type )
| |
- | {
| |
- | switch( type )
| |
- | {
| |
- | case LINUX: return new CLinuxWindow();
| |
- | break;
| |
- | case WINDOWS: return new CWinWindow();
| |
- | break;
| |
- | case MAC: return new CMacWindow();
| |
- | break;
| |
- | }
| |
- | return 0;
| |
- | }
| |
- |
| |
- | static CWindowImp *makeWindow()
| |
- | {
| |
- | // Будем считать, что мы узнали какая у нас ОС
| |
- | return getWindowImp(CWindowFactory::LINUX);
| |
- | }
| |
- | };
| |
- |
| |
- | class CWindow
| |
- | {
| |
- | public:
| |
- | void draw(){ getWindowImp()->drawWindow(); }
| |
- | CWindowImp *getWindowImp(){ return CWindowFactory::makeWindow(); }
| |
- | };
| |
- |
| |
- | int main()
| |
- | {
| |
- | CWindow win;
| |
- | win.draw();
| |
- | }</source>
| |
- |
| |
| == Низкая связанность (Low Coupling) == | | == Низкая связанность (Low Coupling) == |
| == Приспособленец (Flyweight) == | | == Приспособленец (Flyweight) == |
Строка 784: |
Строка 361: |
| == Команда (Command), Действие (Action) или Транзакция (Транзакция) == | | == Команда (Command), Действие (Action) или Транзакция (Транзакция) == |
| == Наблюдатель (Observer), Опубликовать - подписаться (Publish - Subscribe) или Delegation Event Model == | | == Наблюдатель (Observer), Опубликовать - подписаться (Publish - Subscribe) или Delegation Event Model == |
- | <source lang="cpp">
| |
- | #include <iostream>
| |
- | #include <vector>
| |
- | #include <algorithm>
| |
- |
| |
- | class CObserver;
| |
- |
| |
- | class CModel
| |
- | {
| |
- | std::vector<CObserver*> m_views;
| |
- | int m_nValue;
| |
- | public:
| |
- | void attach(CObserver *po) { m_views.push_back( po ); }
| |
- | void detach(CObserver *po)
| |
- | {
| |
- | std::vector<CObserver*>::iterator iter = std::find( m_views.begin(), m_views.end(), po);
| |
- | if( iter != m_views.end() )
| |
- | {
| |
- | m_views.erase( iter );
| |
- | }
| |
- | }
| |
- | void setValue(int val)
| |
- | {
| |
- | m_nValue = val;
| |
- | notify();
| |
- | }
| |
- | int getValue() { return m_nValue; }
| |
- | void notify();
| |
- | };
| |
- |
| |
- | class CObserver
| |
- | {
| |
- | CModel *m_pModel;
| |
- | public:
| |
- | CObserver(CModel *pMod)
| |
- | {
| |
- | m_pModel = pMod;
| |
- | m_pModel->attach(this);
| |
- | }
| |
- |
| |
- | virtual ~CObserver()
| |
- | {
| |
- | m_pModel.detach(this);
| |
- | }
| |
- |
| |
- | virtual void update() = 0;
| |
- | protected:
| |
- | CModel *getModel() { return m_pModel; }
| |
- | };
| |
- |
| |
- | class CViewDiagram: public CObserver
| |
- | {
| |
- | public:
| |
- | CViewDiagram(CModel *pMod): CObserver(pMod){}
| |
- | void update() { std::cout << "CViewDiagram: " << getModel()->getValue() << std::endl; }
| |
- | };
| |
- |
| |
- | class CViewDocument: public CObserver
| |
- | {
| |
- | public:
| |
- | CViewDocument(CModel *pMod): CObserver(pMod){}
| |
- | void update() { std::cout << "CViewDocument: " << getModel()->getValue() << std::endl; }
| |
- | };
| |
- |
| |
- | void CModel::notify()
| |
- | {
| |
- | for (size_t i = 0; i < m_views.size(); i++)
| |
- | m_views[i]->update();
| |
- | }
| |
- |
| |
- | int main()
| |
- | {
| |
- | CModel model;
| |
- | CViewDocument doc( &model );
| |
- | CViewDiagram diagr( &model );
| |
- |
| |
- | for( int n= 0; n < 10; ++n)
| |
- | {
| |
- | model.setValue( n );
| |
- | if( n ==5 )
| |
- | model.detach( &diagr );
| |
- | }
| |
- | }</source>В роли CObserver в данном примере выступают классы виды: CViewDiagram с CViewDocument. Они получают уведомления об изменении в модели.
| |
- | Вывод:
| |
- | <source lang="cpp">CViewDocument: 0
| |
- | CViewDiagram: 0
| |
- | CViewDocument: 1
| |
- | CViewDiagram: 1
| |
- | CViewDocument: 2
| |
- | CViewDiagram: 2
| |
- | CViewDocument: 3
| |
- | CViewDiagram: 3
| |
- | CViewDocument: 4
| |
- | CViewDiagram: 4
| |
- | CViewDocument: 5
| |
- | CViewDiagram: 5
| |
- | CViewDocument: 6
| |
- | CViewDocument: 7
| |
- | CViewDocument: 8
| |
- | CViewDocument: 9</source>
| |
- |
| |
| == Не разговаривайте с неизвестными (Don't talk to strangers) == | | == Не разговаривайте с неизвестными (Don't talk to strangers) == |
| == Посетитель (Visitor) == | | == Посетитель (Visitor) == |
| == Посредник (Mediator) == | | == Посредник (Mediator) == |
| == Состояние (State) == | | == Состояние (State) == |
- | <source lang="cpp">#include <iostream>
| |
- |
| |
- | class CSocket;
| |
- | class CStateOpen;
| |
- | class CStateRead;
| |
- | class CStateClose;
| |
- |
| |
- | class CState
| |
- | {
| |
- | public:
| |
- | virtual ~CState() {}
| |
- |
| |
- | virtual void open(CSocket *s) { std::cout << "Already open socket" << std::endl; }
| |
- | virtual void read(CSocket *s) { std::cout << "Already read socket" << std::endl; }
| |
- | virtual void close(CSocket *s) { std::cout << "Already close socket" << std::endl; }
| |
- | };
| |
- |
| |
- | class CSocket
| |
- | {
| |
- | CState *m_pCurrentState;
| |
- | public:
| |
- | CSocket();
| |
- | void setCurrent(CState *p){ m_pCurrentState = p; }
| |
- | void open() { m_pCurrentState->open(this); }
| |
- | void read() { m_pCurrentState->read(this); }
| |
- | void close() { m_pCurrentState->close(this); }
| |
- | };
| |
- |
| |
- | class CStateOpen: public CState
| |
- | {
| |
- | public:
| |
- | CStateOpen(){ std::cout << " CStateOpen" << std::endl; }
| |
- | ~CStateOpen(){ std::cout << " ~CStateOpen" << std::endl; }
| |
- | virtual void read(CSocket *s);
| |
- | virtual void close(CSocket *s);
| |
- | };
| |
- |
| |
- | class CStateRead: public CState
| |
- | {
| |
- | public:
| |
- | CStateRead(){ std::cout << " CStateRead" << std::endl; }
| |
- | ~CStateRead(){ std::cout << " ~CStateRead" << std::endl; }
| |
- | virtual void open(CSocket *s) { std::cout << " Socket already open..." << std::endl; }
| |
- | virtual void close(CSocket *s);
| |
- | };
| |
- |
| |
- | class CStateClose: public CState
| |
- | {
| |
- | public:
| |
- | CStateClose(){ std::cout << " CStateClose" << std::endl; }
| |
- | ~CStateClose(){ std::cout << " ~CStateClose" << std::endl; }
| |
- | virtual void open(CSocket *s)
| |
- | {
| |
- | std::cout << " Open closing socket" << std::endl;
| |
- | s->setCurrent( new CStateOpen());
| |
- | }
| |
- | virtual void read(CSocket *s) { std::cout << " Error: Don't read closing socket" << std::endl; }
| |
- | };
| |
- |
| |
- | CSocket::CSocket()
| |
- | {
| |
- | m_pCurrentState = new CStateClose();
| |
- | }
| |
- |
| |
- | void CStateOpen::read(CSocket *s)
| |
- | {
| |
- | std::cout << " Read socket" << std::endl;
| |
- | s->setCurrent( new CStateRead());
| |
- | }
| |
- | void CStateOpen::close(CSocket *s)
| |
- | {
| |
- | std::cout << " Close socket after opening" << std::endl;
| |
- | s->setCurrent( new CStateClose());
| |
- | }
| |
- |
| |
- | void CStateRead::close(CSocket *s)
| |
- | {
| |
- | std::cout << " Close socket after reading" << std::endl;
| |
- | s->setCurrent( new CStateClose());
| |
- | }
| |
- |
| |
- | int main()
| |
- | {
| |
- | void(CSocket::*ptrs[])() = { &CSocket::open, &CSocket::read, &CSocket::close };
| |
- | CSocket sock;
| |
- | int num;
| |
- | while( 1 )
| |
- | {
| |
- | std::cout << "Enter 0/2: ";
| |
- | std::cin >> num;
| |
- | (sock.*ptrs[num])();
| |
- | }
| |
- | }</source>В данном случае классами состояния являются: CStateOpen, CStateRead и CStateClose. Которые в случае того или иного действия с сокетом меняются...
| |
- | <source lang="bash"> CStateClose
| |
- | Enter 0/2: 0
| |
- | Open closing socket
| |
- | CStateOpen
| |
- | Enter 0/2: 1
| |
- | Read socket
| |
- | CStateRead
| |
- | Enter 0/2: 2
| |
- | Close socket after reading
| |
- | CStateClose
| |
- | Enter 0/2: 0
| |
- | Open closing socket
| |
- | CStateOpen
| |
- | Enter 0/2: 2
| |
- | Close socket after opening
| |
- | CStateClose
| |
- | Enter 0/2: 1
| |
- | Error: Don't read closing socket
| |
- | </source>
| |
- |
| |
| == Стратегия (Strategy) == | | == Стратегия (Strategy) == |
| == Хранитель (Memento) == | | == Хранитель (Memento) == |
| == Цепочка обязанностей (Chain of Responsibility) == | | == Цепочка обязанностей (Chain of Responsibility) == |
| == Шаблонный метод (Template Method) == | | == Шаблонный метод (Template Method) == |
- | <source lang="cpp">#include <iostream>
| |
- |
| |
- | class CApp
| |
- | {
| |
- | public:
| |
- | void openDocument()
| |
- | {
| |
- | //...
| |
- | doOpenDocument();
| |
- | //...
| |
- | }
| |
- |
| |
- | protected:
| |
- | virtual void doOpenDocument() { std::cout << "Open simple document" << std::endl; }
| |
- | };
| |
- |
| |
- | class CXmlApp: public CApp
| |
- | {
| |
- | protected:
| |
- | void doOpenDocument() { std::cout << "Open XML document" << std::endl; }
| |
- | };
| |
- |
| |
- | class CTxtApp: public CApp
| |
- | {
| |
- | protected:
| |
- | void doOpenDocument() { std::cout << "Open TXT document" << std::endl; }
| |
- | };
| |
- |
| |
- | int main()
| |
- | {
| |
- | CApp *pApps[] = { &CApp(), &CXmlApp(), &CTxtApp() };
| |
- | for( int n = 0; n < 3; ++n )
| |
- | pApps[n]->openDocument();
| |
- | return 0;
| |
- | }</source>В данном примере метод doOpenDocument является шаблонным методом.
| |
- | Вывод:
| |
- | <source lang="bash">Open simple document
| |
- | Open XML document
| |
- | Open TXT document</source>
| |
- |
| |
| == Высокое зацепление (High Cohesion) == | | == Высокое зацепление (High Cohesion) == |
| == Контроллер (Controller) == | | == Контроллер (Controller) == |