• 常用设计模式


    Factory 模式

    //Product.h

    #ifndef _PRODUCT_H_

    #define _PRODUCT_H_ 

    class Product

    {

    public: 

             virtual ~Product() = 0;

    protected: 

             Product();

    }; 

    class ConcreteProduct:public Product

    {

    public: 

             ~ConcreteProduct(); 

             ConcreteProduct();   

    }; 

    #endif

    //Product.cpp 

    #include "Product.h"

    #include <iostream>

    using namespace std; 

    Product::Product()

    Product::~Product()

    ConcreteProduct::ConcreteProduct()

             cout<<"ConcreteProduct...."<<endl;

    ConcreteProduct::~ConcreteProduct()

    }

      

    //Factory.h 

    #ifndef _FACTORY_H_

    #define _FACTORY_H_ 

    class Product; 

    class Factory

    {

    public: 

             virtual ~Factory() = 0; 

             virtual Product* CreateProduct() = 0; 

    protected: 

             Factory(); 

    };

    class ConcreteFactory:public Factory

    {

    public: 

             ~ConcreteFactory(); 

             ConcreteFactory(); 

             Product* CreateProduct();

    }; 

    #endif

    //Factory.cpp 

    #include "Factory.h"

    #include "Product.h" 

    #include <iostream>

    using namespace std; 

    Factory::Factory()

    Factory::~Factory()

    {

    ConcreteFactory::ConcreteFactory()

    cout<<"ConcreteFactory....."<<endl;

    ConcreteFactory::~ConcreteFactory()

    Product* ConcreteFactory::CreateProduct()

    return new ConcreteProduct();

    }

      

    //main.cpp 

    #include "Factory.h"

    #include "Product.h"

    #include <iostream>

    using namespace std; 

    int main(int argc,char* argv[])

    Factory* fac=new ConcreteFactory(); 

    Product* p =fac->CreateProduct(); 

    return 0;

    }

    代码说明

       

    示例代码中给出的是 Factory 模式解决父类中并不知道具体要实例化哪一个具体的子类

    的问题,至于为创建对象提供接口问题,可以由 Factory 中附加相应的创建操作例如

    Create***Product()即可

    Factory 模式也带来至少以下两个问题:

        1)如果为每一个具体的 ConcreteProduct 类的实例化提供一个函数体,那么我们可能不得不在系统中添加了一个方法来处理这个新建的 ConcreteProduct,这样 Factory 的接口永远就不肯能封闭(Close 。当然我们可以通过创建一个 Factory 的子类来通过多态实现这一点,但是这也是以新建一个类作为代价的。    2)在实现中我们可以通过参数化工厂方法,即给 FactoryMethod()传递一个参数用以决定是创建具体哪一个具体的 Product(实际上笔者在VisualCMCS 中也正是这样做的) 。当然也可以通过模板化避免 1)中的子类创建子类,其方法就是将具体 Product 类作为模板参数,实现起来也很简单。

    Singleton模式

    //Singleton.h 

    #ifndef _SINGLETON_H_

    #define _SINGLETON_H_ 

    #include <iostream>

    using namespace std; 

    class Singleton

    {

    public: 

             static Singleton* Instance();

    protected: 

             Singleton(); 

    private: 

             static Singleton* _instance; 

    }; 

    #endif //~_SINGLETON_H_

    //Singleton.cpp 

    #include "Singleton.h"

    #include <iostream>

    using namespace std; 

    Singleton* Singleton::_instance = 0;

    Singleton::Singleton()

             cout<<"Singleton...."<<endl;

    Singleton* Singleton::Instance()

             if (_instance == 0) 

             { 

                      _instance = new Singleton();

            } 

             return _instance;

    }

    //main.cpp 

    #include "Singleton.h" 

    #include <iostream>

    using namespace std; 

    int main(int argc,char* argv[])

             Singleton* sgn = Singleton::Instance(); 

             return 0;

    Iterator 模式

    //Aggregate.h

    class Iterator;

    typedef int Object;

    class Interator;

    class Aggregate

    {

    public: 

    virtual ~Aggregate();

      virtual Iterator* CreateIterator() = 0;

      virtual Object GetItem(int idx) = 0;

      virtual int GetSize() = 0;

    protected:

            Aggregate();

    };

    class ConcreteAggregate:public Aggregate

    {

    public: 

             enum {SIZE = 3};

            ConcreteAggregate();

            ~ConcreteAggregate();

            Iterator* CreateIterator();

            Object GetItem(int idx);

            int GetSize();

    private: 

    Object _objs[SIZE];

    };

    //Iterator.cpp

    #include "Iterator.h"

    #include "Aggregate.h"

    #include <iostream>

    using namespace std;

    Iterator::Iterator()

    {

    }

    Iterator::~Iterator()

    {

    }

    ConcreteIterator::ConcreteIterator(Aggregate*

    ag , int idx)

    this->_ag = ag; 

    this->_idx = idx;

    }

    ConcreteIterator::~ConcreteIterator()

    {

    }

    Object ConcreteIterator::CurrentItem()

    return _ag->GetItem(_idx);

    }

    void ConcreteIterator::First()

    _idx = 0;

    }

    void ConcreteIterator::Next()

    if (_idx < _ag->GetSize()) 

    _idx++;

    }

    bool ConcreteIterator::IsDone()

    return (_idx == _ag->GetSize());

    }

    //Aggregate.cpp

    #include "Aggregate.h" #include "Iterator.h"

    #include <iostream> using namespace std;

    Aggregate::Aggregate() { }

    Aggregate::~Aggregate() { }

    ConcreteAggregate::ConcreteAggregate()

             for (int i = 0; i < SIZE; i++) 

             _objs[i] = i;

    }

    ConcreteAggregate::~ConcreteAggregate() { }

    Iterator* ConcreteAggregate::CreateIterator()

             return new ConcreteIterator(this);

    }

    Object ConcreteAggregate::GetItem(int idx)

             if (idx < this->GetSize()) 

                      return _objs[idx]; 

             else 

                      return -1;

    int ConcreteAggregate::GetSize()

             return SIZE;

    }

      //main.cpp 

    #include "Iterator.h"

    #include "Aggregate.h" 

    #include <iostream>

    using namespace std; 

    int main(int argc,char* argv[])

    Aggregate* ag = new ConcreteAggregate(); 

    Iterator* it = new ConcreteIterator(ag);

       

    for (; !(it->IsDone()) ; it->Next())

     {

            cout<<it->CurrentItem()<<endl;

     } 

    return 0;

    }

         

    /Iterator.h

    class Aggregate;

    typedef int Object;

    class Iterator

    {

    public: 

             virtual ~Iterator(); 

             virtual void First() = 0; 

             virtual void Next() = 0; 

             virtual bool IsDone()  = 0; 

             virtual Object CurrentItem() = 0;

    protected: 

             Iterator();

    };

    class ConcreteIterator:public Iterator

    {

    public: 

    ConcreteIterator(Aggregate* ag , int idx =0); 

             ~ConcreteIterator(); 

             void First(); 

             void Next(); 

             bool IsDone(); 

             Object CurrentItem();

    private: 

             Aggregate* _ag;  int _idx;

    };

     代码说明

       

    Iterator 模式的实现代码很简单,实际上为了更好地保护 Aggregate 的状态,我们可以尽

    量减小Aggregatepublic接口, 而通过将Iterator对象声明位Aggregate的友元来给予Iterator一些特权,获得访问 Aggregate私有数据和方法的机会。

       

    Iterator 模式的应用很常见, 我们在开发中就经常会用到 STL 中预定义好的 Iterator 来对

    STL 类进行遍历(VectorSet 等) 

       

       

       

       

       

    Observer 模式

       

    //Subject.h 

    #include <list>

    #include <string>

    using namespace std;

    typedef string State;

    class Observer;

    class Subject

    {

    public:

             virtual ~Subject();

            virtual void Attach(Observer* obv);

        virtual void Detach(Observer* obv);

            virtual void Notify();

    virtual void SetState(const State& st) = 0;

             virtual State GetState() = 0;

    protected:

            Subject();

    private:

             list<Observer* >* _obvs;

    };

    class ConcreteSubject:public Subject

    {

    public:

            ConcreteSubject();

            ~ConcreteSubject();

             State GetState();

            void SetState(const State& st);

    private:

             State _st;

    };

    //Subject.cpp

    #include "Subject.h"

    #include "Observer.h"

    #include <iostream>

    #include <list>

    using namespace std;

    typedef string state;

    Subject::Subject()

    { //在模板的使用之前一定要 new,创建

             _obvs = new list<Observer*>;

    }

    Subject::~Subject() { }

    void Subject::Attach(Observer* obv)

             _obvs->push_front(obv);

    }

    void Subject::Detach(Observer* obv)

    {

            if (obv != NULL)

            _obvs->remove(obv);

    }

    void Subject::Notify()

    {

            list<Observer*>::iterator it;

            it = _obvs->begin();

            for (;it != _obvs->end();it++)

            {   //关于模板和 iterator 的用法

            (*it)->Update(this);

             }

    }

    ConcreteSubject::ConcreteSubject()

    {

            _st = '';

    }

    ConcreteSubject::~ConcreteSubject(){ }

    State ConcreteSubject::GetState()

             return _st;

    }

    void ConcreteSubject::SetState(const State& st)

    {

             _st = st;

    }

    //Observer.h

    #include "Subject.h"

    #include <string>

    using namespace std;

    typedef string State;

    class Observer

    {

    public:

             virtual ~Observer();

            virtual void Update(Subject* sub) = 0;

            virtual void PrintInfo() = 0;

    protected:

            Observer();

            State _st;

    };

    class ConcreteObserverA:public Observer

    {

    public:

             virtual Subject* GetSubject();

            ConcreteObserverA(Subject* sub);

            virtual ~ConcreteObserverA();

    //传入 Subject 作为参数,这样可以让一个

    View 属于多个的 Subject

            void  Update(Subject* sub);

            void PrintInfo();

    private:

     Subject* _sub;

    };

    class ConcreteObserverB:public Observer

    {

    public:

             virtual Subject* GetSubject();

             ConcreteObserverB(Subject* sub);

            virtual ~ConcreteObserverB();

    //传入 Subject 作为参数,这样可以让一个

    View 属于多个的 Subject

            void  Update(Subject* sub);

            void PrintInfo();

    private:

             Subject* _sub;

    };

    //Observer.cpp

    #include "Observer.h"

    #include "Subject.h"

    #include <iostream>

    #include <string>

    using namespace std;

    Observer::Observer()

             _st = '';

    Observer::~Observer() { }

    ConcreteObserverA::ConcreteObserverA(Subject* sub)

             _sub = sub;

            _sub->Attach(this);

    }

    ConcreteObserverA::~ConcreteObserverA()

    {

            _sub->Detach(this);

             if (_sub != 0)

            delete _sub;

    }

    Subject* ConcreteObserverA::GetSubject()

    {

            return _sub;

    }

    void ConcreteObserverA::PrintInfo()

    {

            cout<<"ConcreteObserverA

    observer..."<<_sub->GetState()<<endl;

    }

    Void ConcreteObserverA::

    Update(Subject* sub)

             _st = sub->GetState();

             PrintInfo();

    }

    ConcreteObserverB::ConcreteObserverB(Subject* sub)

    {

            _sub = sub;

            _sub->Attach(this);

    }

    //main.cpp 

    #include "Subject.h"

    #include "Observer.h"

    #include <iostream>

    using namespace std;

       

    int main(int argc,char* argv[])

    {

    ConcreteSubject* sub=newConcreteSubject();

    Observer* o1 =new ConcreteObserverA(sub);

    Observer* o2 =new ConcreteObserverB(sub);

     sub->SetState("old");

     sub->Notify();

     sub->SetState("new"); //    

                                        //Observer 调用

     sub->Notify();

     return 0;

    }

     Observer 模式的实现中,Subject 维护一个list 作为存储其所有观察者的容器。每当

    调用Notify操作就遍历list中的Observer对象,并广播通知改变状态 (调用ObserverUpdate操作) 。目标的状态 state 可以由 Subject 自己改变(示例) ,也可以由 Observer 的某个操作引起 state 的改变(可调用 Subject SetState 操作) Notify 操作可以由 Subject 目标主动广播(示例) ,也可以由 Observer观察者来调用(因为 Observer 维护一个指向 Subject 的指针)  

       

    运行示例程序,可以看到当 Subject 处于状态"old"时候,依赖于它的两个观察者都显

    示"old" ,当目标状态改变为"new"的时候,依赖于它的两个观察者也都改变为"new" 

    Observer 是影响极为深远的模式之一,也是在大型系统开发过程中要用到的模式之一。

    除了 MFC Struts提供了 MVC 的实现框架, Java 语言中还提供了专门的接口实现 Observer模式:通过专门的类 Observable  Observer 接口来实现 MVC 编程模式,其 UML 图可以表示为:

       

    Java 中实现 MVC  UML 图。

    这里的 Observer 就是观察者,Observable 则充当目标 Subject 的角色。

       

    Observer 模式也称为发布-订阅(publish-subscribe ,目标就是通知的发布者,观察者则是通知的订阅者(接受通知) 

     

  • 相关阅读:
    hdu6060[贪心+dfs] 2017多校3
    Codeforces 547B. Mike and Feet[单调栈/队列]
    Codeforces 545E. Paths and Trees[最短路+贪心]
    gitignore使用
    es学习
    google浏览器安装jsonview
    sychronized关键字底层详解加锁升级过程
    idea 中 “XXX has broken path” 错误解决
    kafka高并发读写的原因
    window redis版本 安装
  • 原文地址:https://www.cnblogs.com/fuyou/p/3233216.html
Copyright © 2020-2023  润新知