Observer模式是应用最多、影响最广的设计模式之一,因为Observer的一个实例Model/View/Control(MVC)结构在系统开发架构设计中有着很重要的地位和意义,MVC实现了业务逻辑和表示层的解耦。在MFC(微软基础类库)中,Doc/View(文档视图结构)提供了实现MVC的框架结构。
在GOF的《设计模式:可复用面向对象软件的基础》一书中对观察者模式是这样定义的:定义对象的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。当一个对象发生了变化,关注它的对象就会得到通知;这种交互也成为发布-订阅(publish-subscribe)。
MVC框架是模型-视图-控制器的缩写,一种软件设计典范。用一种业务逻辑、数据、显示界面分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能。在一个逻辑的图形化用户界面的结构中MVC分层有助于管理复杂的应用程序,因为可以在一个时间内专注的关注一个方面,可以在不依赖业务逻辑的情况下专注于视图设计,同时也将应用程序的测试更加容易。
介绍
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并被自动更新。
主要解决:一个对象状态改变并给其它对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
如何解决:使用面向对象技术,可以将这种依赖关系弱化。
关键代码:在抽象类里有一个arrayList存放观察者们。
应用实例:1、拍卖的时候,拍卖师观察最高价格,然后通知给其它竞价者竞价。2、西游记里面悟空请求菩萨降服红孩儿,菩萨洒了一地水找来一个老乌龟,这个老乌龟就是观察者(菩萨是被观察者),他观察菩萨这个动作。
优点:1、观察者和被观察者是抽象耦合的。2、建立一套触发机制。
缺点:1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
使用场景:
一个抽象模型有两个方面,其中一个方面发依赖于另外一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
一个对象的改变将导致其它一个或多个对象发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
一个对象必须通知其他对象,而并不知道这些对象是谁。
需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
注意事项:1、应避免循环引用。2、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式(多线程)。
示例1
对同一组数据进行统计分析的时候,我们希望能够提供多种形式的表示(例如以表格形式进行显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据,我们当然需要当数据改变的时候,所有统计的显示都能同时改变、Observer模式就是解决了这一个问题。
UML类图
Subject(目标)
目标知道它的观察者,可以有任意多个观察者观察用一个目标。提供注册和删除观察者对象的接口。
Observer(观察者)
为所有观察目标的观察者对象提供一个公共的更新接口。
ConcreteSubject(具体目标)
将有关状态的情况广播给各ConcreteObserver对象。
ConcreteObserver(具体观察者)
维护一个指向ConcreteSubject对象的指针。用于当具体观察者初始化时直接存入ConcreteSubject对象(初始化就订阅ConcreteSubject主题)。
存储有有关状态,这些状态应与目标的状态保持一致。实现Observer公共更新接口以便使自身状态和目标状态保持一致。
观察者模式按照以下方式进行协作:
当ConcreteSubject发生任何可能导致其观察者与其本身状态不一致的改变时,它将通知它的各个观察者。在得到一个具体目标的改变通知后,ConcreteObserver对象可收到目标对象的信息。ConcreteObserver使用这些信息使它的状态和目标对象的状态保持一致。
#include
#include
#include
using namespace std;
class Observer
{
public:
virtual ~Observer(){};
virtual void Update(int) = 0;
};
class Subject
{
public:
virtual ~Subject(){};
virtual void Attach(Observer*) = 0;
virtual void Detach(Observer*) = 0;
virtual void Notify() = 0;
};
class ConcreateObserver:public Observer
{
public:
ConcreateObserver(Subject *pSubject):_pSubject(pSubject)
{
//在目标中注册当前观察者(此处的观察者是广义上的观察者,目标并不知道具体谁要观察它,目标只进行广播即可)
this->_pSubject->Attach(this);\
cout << "I'am the observer1\n" << endl;
}
void Update(int value) override
{
cout << "ConcreteObserver get the update.New State:" << value << endl;
}
private:
Subject *_pSubject;
};
class ConcreateObserver2:public Observer
{
public:
ConcreateObserver2(Subject *pSubject):_pSubject(pSubject)
{
//在目标中注册当前观察者
this->_pSubject->Attach(this);
cout << "I'm the observer2\n" << endl;
}
void Update(int value) override
{
cout << "ConcreteObserver2 get the update.New State:" << value << endl;
}
private:
Subject *_pSubject;
};
class ConcreateSubject:public Subject
{
public:
void SetState(int state)
{
_iState = state;
}
void Attach(Observer *pObserver) override
{
_pObserverList.push_back(pObserver);
}
void Detach(Observer *pObserver) override
{
_pObserverList.remove(pObserver);
}
void Notify() override
{
auto begin = _pObserverList.begin();
auto end = _pObserverList.end();
while(begin != end)
{
(*begin)->Update(_iState);
begin++;
}
}
private:
list _pObserverList;
int _iState;
};
int main()
{
//创建目标
ConcreateSubject *pSubject = new ConcreateSubject();
//创建观察者
Observer *pObserver = new ConcreateObserver(pSubject);
Observer *pObserver2 = new ConcreateObserver2(pSubject);
//改变当前状态
pSubject->SetState(2);
//通知给所有广义上的观察者改变状态
pSubject->Notify();
//去除某个观察者
pSubject->Detach(pObserver);
//改变当前状态
pSubject->SetState(3);
//重新广播通知
pSubject->Notify();
//结束,释放对象
delete pObserver;
delete pObserver2;
delete pSubject;
return 0
}
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式作为一种创建模式,一般在创建复杂对象时,考虑使用;在创建简单对象时,建议直接new完成一个实例对象的创建。
抽象工厂模式提供创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
当存在多个产品系列,而客户端只使用一个系列的产品时,可以考虑使用抽象工厂模式。
#include
#include
using namespace std;
//抽象上衣类
class Coat
{
public:
virtual const string& color() = 0;
};
//黑色上衣类
class BlackCoat:public Coat
{
public:
BlackCoat():Coat(),m_strColor("Black Coat")
{
}
const string& color() override
{
cout << m_strColor.data() << endl;
return m_strColor;
}
private:
string m_strColor;
};
//白色上衣类
class WhiteCoat:public Coat
{
public:
WhiteCoat():Coat(),m_strColor("White Coat")
{
}
const string& color() override
{
cout << m_strColor.data() << endl;
return m_strColor;
}
private:
string m_strColor;
};
//抽象裤子类
class Pants
{
public:
virtual const string& color() = 0;
};
//黑色裤子类
class BlackPants:public Pants
{
public:
BlackPants():Pants(),m_strColor("Black Pants")
{
}
const string& color() override
{
cout << m_strColor.data() << endl;
return m_strColor;
}
private:
string m_strColor;
};
//白色裤子类
class WhitePants:public Pants
{
public:
WhitePants():Pants()
{
m_strColor = "White Pants";
}
const string& color() override
{
cout << m_strColor << endl;
return m_strColor;
}
private:
string m_strColor;
};
//抽象工厂类,提供衣服创建接口
class Factory
{
public:
//上衣创建接口,返回抽象上衣类
virtual Coat* createCoat() = 0;
//裤子创建接口,返回抽象裤子类
virtual Pants* createPants() = 0;
};
//创建白色衣服工厂类,实现创建白色上衣和白色裤子的接口
class WhiteFactory:public Factory
{
public:
Coat* createCoat() override
{
return new WhiteCoat();
}
Pants* createPants() override
{
return new WhitePants();
}
};
//创建黑色衣服工厂类,实现创建黑色上衣和白色裤子的接口
class BlackFactory:public Factory
{
public:
Coat *createCoat() override
{
return new BlackCoat();
}
Pants *createPants() override
{
return new BlackPants();
}
};
int main()
{
WhiteFactory *whiteFactory = new WhiteFactory();
Coat * coat = whiteFactory->createCoat();
// WhiteCoat *whiteCoat = factory->createCoat();
coat->color();
return 0;
}