1.Observer(观察者模式)
主题对象管理某些数据,当主题内的数据发生改变,就通知观察者,观察者已经注册主题便会在主题数据发生改变时能够收到更新。一旦数据改变,新的数据会以某种形式送到观察者手上。
观察者模式定义了对象之间的一对多关系,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

例子:
#**include** <iostream>
#**include** <set>
#**include** <string>
**using** **namespace** std;
/////////////////////抽象模式定义
**class** CObservable;
//观察者,纯虚基类
**class** CObserver
{
**public**:
CObserver::CObserver(){};
**virtual** CObserver::~CObserver(){};
//当被观察的目标发生变化时,通知调用该方法
//来自被观察者pObs, 扩展参数为pArg
**virtual** **void** Update(CObservable* pObs, **void*** pArg = NULL) = 0;
};
//被观察者,即Subject
**class** CObservable
{
**public**:
CObservable() : m_bChanged(**false**) {};
**virtual** ~CObservable() {};
//注册观察者
**void** Attach(CObserver* pObs);
//注销观察者
**void** Detach(CObserver* pObs);
//注销所有观察者
**void** DetachAll();
//若状态变化,则遍历观察者,逐个通知更新
**void** Notify(**void*** pArg = NULL);
//测试目标状态是否变化
**bool** HasChanged();
//获取观察者数量
**int** GetObserversCount();
**protected**:
//设置状态变化!!!必须继承CObservable才能设置目标状态
**void** SetChanged();
//初始化目标为未变化状态
**void** ClearChanged();
**private**:
**bool** m_bChanged; //状态
set<CObserver*> m_setObs; //set保证目标唯一性
};
/////////////////////抽象模式实现
**void** CObservable::Attach(CObserver* pObs)
{
**if** (!pObs) **return**;
m_setObs.insert(pObs);
}
**void** CObservable::Detach(CObserver* pObs)
{
**if** (!pObs) **return**;
m_setObs.erase(pObs);
}
**void** CObservable::DetachAll()
{
m_setObs.clear();
}
**void** CObservable::SetChanged()
{
m_bChanged = **true**;
}
**void** CObservable::ClearChanged()
{
m_bChanged = **false**;
}
**bool** CObservable::HasChanged()
{
**return** m_bChanged;
}
**int** CObservable::GetObserversCount()
{
**return** m_setObs.size();
}
**void** CObservable::Notify(**void*** pArg /* = NULL */)
{
**if** (!HasChanged()) **return**;
cout << "notify observers…" << endl;
ClearChanged();
set<CObserver*>::iterator itr = m_setObs.begin();
**for** (; itr != m_setObs.end(); itr++)
{
(*itr)->Update(**this**, pArg);
}
}
/////////////////////具体应用类定义和实现
//bloger是发布者,即被观察者(subject)
**class** CBloger : **public** CObservable
{
**public**:
**void** Publish(**const** string &strContent)
{
cout << "bloger publish, content: " << strContent << endl;
SetChanged();
Notify(**const_cast**<**char***>(strContent.c_str()));
}
};
//portal是发布者,即被观察者(subject)
**class** CPortal : **public** CObservable
{
**public**:
**void** Publish(**const** string &strContent)
{
cout << "portal publish, content: " << strContent << endl;
SetChanged();
Notify(**const_cast**<**char***>(strContent.c_str()));
}
};
//RSS阅读器,观察者
**class** CRSSReader : **public** CObserver
{
**public**:
CRSSReader(**const** string &strName) : m_strName(strName){}
**virtual** **void** Update(CObservable* pObs, **void*** pArg = NULL)
{
**char*** pContent = **static_cast**<**char***>(pArg);
//观察多个目标
**if** (**dynamic_cast**<CBloger*>(pObs))
{
cout << m_strName << " updated from bloger, content: " << pContent << endl;
}
**else** **if** (**dynamic_cast**<CPortal*>(pObs))
{
cout << m_strName << " updated from portal, content: " << pContent << endl;
}
}
**private**:
string m_strName;
};
//Mail阅读器,观察者
**class** CMailReader : **public** CObserver
{
**public**:
CMailReader(**const** string &strName) : m_strName(strName){}
**virtual** **void** Update(CObservable* pObs, **void*** pArg = NULL)
{
**char*** pContent = **static_cast**<**char***>(pArg);
**if** (**dynamic_cast**<CBloger*>(pObs))
{
cout << m_strName << " updated from bloger, content: " << pContent << endl;
}
**if** (**dynamic_cast**<CPortal*>(pObs))
{
cout << m_strName << " updated from portal, content: " << pContent << endl;
}
}
**private**:
string m_strName;
};
/////////////////Main
**int** main()
{
//目标(被观察者)
CBloger* pBloger = **new** CBloger();
CPortal* pPortal = **new** CPortal();
//观察者. 一个观察者可以观察多个目标
CRSSReader* pRssReader = **new** CRSSReader("rss reader");
CMailReader* pMailReader = **new** CMailReader("mail reader");
pBloger->Attach(pRssReader); //bloger注册观察者
pBloger->Attach(pMailReader); //bloger注册观察者
pPortal->Attach(pRssReader); //portal注册观察者
pPortal->Attach(pMailReader); //portal注册观察者
//博客发布信息
pBloger->Publish("博客分享设计模式");
cout << endl;
//门户发布信息
pPortal->Publish("门户分享设计模式");
cout << "\nportal detached mail reader" << endl;
pPortal->Detach(pMailReader);
cout << "portal observers count: " << pPortal->GetObserversCount() << endl << endl;
pPortal->Publish("门户分享设计模式");
system("pause");
**return** 0;
}
**2.Command(命令模式)**
命令模式通俗的例子:在餐厅,顾客订餐,把订单交给女招待,女招待拿了订单,交给厨师,厨师根据订单准备食物。一张订单封装了准备食物的请求。女招待的工作就是接受订单,然后调用订单的orderUp()方法。
命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

示例代码:
#**include** <iostream>
#**include** <vector>
**using** **namespace**std;// 烤肉师傅
**class** RoastCook
{
**public**:
**void** MakeMutton()
{ cout << "烤羊肉" <<endl; }**void** MakeChickenWing()
{ cout << "烤鸡翅膀" << endl; }
};
// 抽象命令类
**class** Command
{
**public**:
Command(RoastCook* temp) { receiver = temp; }
**virtual** **void** ExecuteCmd() = 0;
**protected**:
RoastCook* receiver;
};
// 烤羊肉命令
**class** MakeMuttonCmd : **public** Command
{
**public**:
MakeMuttonCmd(RoastCook* temp) : Command(temp) {}
**virtual** **void** ExecuteCmd() { receiver->MakeMutton(); }
};
// 烤鸡翅膀命令
**class** MakeChickenWingCmd : **public** Command
{
**public**:
MakeChickenWingCmd(RoastCook* temp) : Command(temp) {}
**virtual** **void** ExecuteCmd() { receiver->MakeChickenWing(); }
};
// 服务员类
**class** Waiter
{
**public**:
**void** SetCmd(Command* temp);
// 通知执行
**void** Notify();
**protected**:
vector<Command*> m_commandList;
};
**void** Waiter::SetCmd(Command* temp)
{
m_commandList.push_back(temp);
cout << "增加订单" << endl;
}
**void** Waiter::Notify()
{
vector<Command*>::iterator it;
**for** (it=m_commandList.begin(); it!=m_commandList.end(); ++it)
{
(*it)->ExecuteCmd();
}
}
**int** main()
{
// 店里添加烤肉师傅、菜单、服务员等顾客
RoastCook* cook = **new** RoastCook();
Command* cmd1 = **new** MakeMuttonCmd(cook);
Command* cmd2 = **new** MakeChickenWingCmd(cook);
Waiter* girl = **new** Waiter();
// 点菜
girl->SetCmd(cmd1);
girl->SetCmd(cmd2);
// 服务员通知
girl->Notify();
system("pause");
**return** 0;
}
**3.Command 和 Observer 的一些区别**
1.Command封装一个请求对象,Observer定义一种一对多的依赖关系;
2.Command通过对象解耦,Observer可以通过消息解耦;
3.Command可以有执行和撤消操作,所以从某种意义上来说,Command是有序的,Observer是无序的;
4.Command是在主类中通过接口调用各客户端子类的功能,Observer支持主类将更新通知给客户端,然后由客户端自行处理。
[参考]:http://www.cnblogs.com/Random/archive/2012/03/21/2409090.html