Редактирование: Design Patterns

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
= Порождающие паттерны проектирования =
= Порождающие паттерны проектирования =
== Абстрактная фабрика (Abstract Factory, Factory), др. название Инструментарий (Kit) ==
== Абстрактная фабрика (Abstract Factory, Factory), др. название Инструментарий (Kit) ==
-
<source lang="cpp">#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;
 
-
}</source>
 
-
 
== Одиночка (Singleton) ==
== Одиночка (Singleton) ==
=== Статический  ===
=== Статический  ===
Строка 261: Строка 188:
== Прототип (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>
 
-
#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();
 
-
}
 
-
</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: Строка 209:
== Команда (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) ==

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. Wiki.crossplatform.ru:Авторское право). НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!