Observerパターン
GOFでは「デザインパターン:オブジェクト指向における再利用のための」ブックモードの観察者が言うことである:主題多くの間の依存関係の定義、ときにオブジェクトの状態が変化し、それに依存するすべてのオブジェクトが通知され、自動的に更新されました。オブジェクトが変更された場合、その焦点は、オブジェクトが通知され、公開としてこの相互作用も知られている - サブスクライブ(パブリッシュ・サブスクライブ)。目標は、通知は誰にその視聴者を知っている必要はありません発行されたときに、発行者に通知することです。
私は上記のデータとの間の関係としましょう。それは、折れ線グラフ、円グラフや棒グラフであるかどうか、彼らはすべてのデータに依存して、データの変更は、データオブジェクトは、オブジェクトを更新するには、その通知に依存しているとき、そうExcelは、データ変更時、対応するチャートが自動的にそこに再描画されます。
UML类图
件名
(ターゲット)-目標は、その視聴者を知っています。同じ目標を観測する観測者の任意の数があるかもしれません;
-登録するためのインタフェースと削除オブザーバオブジェクトを提供します。
観察者(観察者)
-これらのオブジェクトとして定義され、ターゲット更新インタフェースの変更を通知します。
ConcreteSubject(ターゲット)
-各ConcreteObserverに格納されたオブジェクトの関連状態;
-それは、それぞれの観察者の通知から、状態を変化させます。
ConcreteObserver(特定のビューア)
- ConcreteSubjectは、オブジェクト参照へのポインタを維持する;
-標的の状態と一致しなければならない状態に関する情報を記憶するステップと、
-オブザーバー更新インタフェース目的と一致し、その状態の状態を達成します。
次の方法で協力してObserverパターン:
- 自身で任意の可能ConcreteSubjectビューアが矛盾した状態の変化をもたらす場合には、それは、それぞれの視聴者に通知し、
- 予告変更目標を取得した後、ConcreteObserverオブジェクトがターゲットオブジェクトに情報を照会することができます。ConcreteObserverは、その状態は、対象物と一致している状態に、この情報を使用します。
以下は、タイミング図の呼び出しです:
機会を利用して
オブザーバーモードでは、次のいずれにも使用することができます。
- 抽象モデルは、2つの側面を有する場合の一の態様は、一方に依存しています。彼らは独立して変更して再利用できるように、別々のオブジェクトにカプセル化され、これらの両方。
- オブジェクトに変更する場合、他のオブジェクトは、変更する必要がありますが、変更する必要が正確にどのように多くのオブジェクトを知りません。
- オブジェクトが他のオブジェクトに通知しなければならないが、それは誰も他のオブジェクトがあると仮定できない場合、つまり、あなたは、これらのオブジェクトが緊密に結合されている必要はありません。
コードの実装:
#include<iostream>
#include<list>
using namespace std;
//观察者
class Observer
{
public:
virtual void Update(int) = 0;
};
//被观察的目标
class Subject
{
public:
virtual void Attach(Observer *) = 0;
virtual void Detach(Observer *) = 0;
virtual void Notify() = 0;
};
//具体的观察者
class ConcreteObserver :public Observer
{
public:
ConcreteObserver(Subject* pSubject)
{
m_pSubject = pSubject;
}
void Update(int value)
{
cout << "ConcreteObServer get the update, new State" << value << endl;
}
private:
Subject* m_pSubject; //所要观察的目标
};
//具体的观察者2
class ConcreteObserver2 :public Observer
{
public:
ConcreteObserver2(Subject* pSubject)
{
m_pSubject = pSubject;
}
void Update(int value)
{
cout << "ConcreteObserver2 get the update, new State"<<value<<endl;
}
private:
Subject* m_pSubject;
};
class ConcreteSubject :public Subject
{
public:
void Attach(Observer* pObserver);
void Detach(Observer* pObserver);
void Notify();
void SetState(int state)
{
m_iState = state;
}
private:
list<Observer* > m_ObserverList; //存储观察者
int m_iState;
};
void ConcreteSubject::Attach(Observer* pObserver) //注册观察者
{
m_ObserverList.push_back(pObserver);
}
void ConcreteSubject::Detach(Observer* pObserver) //取消观察者
{
m_ObserverList.remove(pObserver);
}
void ConcreteSubject::Notify()
{
list<Observer*>::iterator it = m_ObserverList.begin();
while (it != m_ObserverList.end())
{
(*it)->Update(m_iState);
++it;
}
}
int main()
{
// Create Subject
ConcreteSubject* pSubject = new ConcreteSubject();
// Create Observer
Observer* pObserver = new ConcreteObserver(pSubject);
Observer* pObserver2 = new ConcreteObserver2(pSubject);
// Change the state
pSubject->SetState(2);
// Register the observer
pSubject->Attach(pObserver);
pSubject->Attach(pObserver2);
pSubject->Notify();
// Unregister the observer
pSubject->Detach(pObserver);
pSubject->SetState(3);
pSubject->Notify();
delete pObserver;
delete pObserver2;
delete pSubject;
}
概要
23個のデザインパターンでモードオブザーバーは、私たちがどこでも基本的に主要なフレームワークは、非常に高いです。パターン全体の本当の理解は、他の人のコードでは、私たちが理解するために非常に大きな助けを持って、私たちの将来の仕事に多かれ少なかれデザインパターンの使用します。私はあなたが、私は追加していきます、コンテンツを追加する必要が発生した場合、将来的には、非常に包括的ではありません思い付いた。また、私たちはより良い提案を考え出すことを願っています。