觀察者模式定義對象間的一對多依賴:當一個對象(主題)狀態改變時,所有依賴它的對象(觀察者)都得到通知並自動更新。
搜索數據庫,有新數據需以多種方式發送(如飛信、郵件、短信等)。觀察者模式完美支撐:只需增加繼承 ITransfer 接口的派生類,維護性極佳。
// ITransfer.h
#pragma once
class ITransfer {
public:
virtual bool DoTransfer(...) = 0;
};
// FetionTransfer.h
#pragma once
#include "ITransfer.h"
class CFetionTransfer : public ITransfer {
public:
CFetionTransfer(); ~CFetionTransfer();
bool DoTransfer(...);
private: ...;
};
// MailTransfer.h
#pragma once
#include "ITransfer.h"
class CMailTransfer : public ITransfer {
public:
CMailTransfer(); ~CMailTransfer();
bool DoTransfer(...);
private: ...;
}
// TransferPool.h
#pragma once
#include "ITransfer.h"
#include <vector>
using namespace std;
class CTransferPool {
private:
vector<ITransfer*> vo;
public:
virtual ~CTransferPool();
void Login(ITransfer* po); // 註冊觀察者
void Logout(ITransfer* po); // 移除觀察者
void Notify(...); // 廣播通知
};
// TransferPool.cpp
#include "TransferPool.h"
CTransferPool::~CTransferPool() {
for (auto vi = vo.begin(); vi != vo.end(); ++vi) {
if (*vi) { delete *vi; *vi = NULL; }
}
}
void CTransferPool::Login(ITransfer* po) { vo.push_back(po); }
void CTransferPool::Logout(ITransfer* po) {
for (auto vi = vo.begin(); vi != vo.end(); ++vi) {
if (*vi == po) { vo.erase(vi); break; }
}
}
void CTransferPool::Notify(...) {
for (auto vi = vo.begin(); vi != vo.end(); ++vi) {
(*vi)->DoTransfer(...);
}
}
void main() {
CTransferPool* m_pTranPool = new CTransferPool();
CFetionTransfer* m_pFetionTran = new CFetionTransfer(...);
CMailTransfer* m_pMailTran = new CMailTransfer(...);
m_pTranPool->Login(m_pFetionTran);
m_pTranPool->Login(m_pMailTran);
while (需要發送消息) {
m_pTranPool->Notify();
}
// 釋放資源
if (m_pTranPool) {
delete m_pTranPool;
m_pTranPool = NULL;
}
}
通過接口抽象與觀察者管理池,實現了消息分發通道的動態增減與解耦,新增通道僅需實現 ITransfer 接口並註冊,符合開閉原則。