Текущая версия |
Ваш текст |
Строка 784: |
Строка 784: |
| == Команда (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) == |