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