常用设计模式

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 的状态,我们可以尽

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

   

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

STL 类进行遍历(Vector、Set 等) 。

   

   

   

   

   

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 = '\0';

}

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 = '\0';

} 

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对象,并广播通知改变状态 (调用Observer的Update操作) 。目标的状态 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) ,目标就是通知的发布者,观察者则是通知的订阅者(接受通知) 。

 

posted on 2013-08-02 17:58  零风腾飞  阅读(222)  评论(0)    收藏  举报

导航