デザイン パターン C++ オブザーバー パターン

現実の世界であろうとソフトウェア システムであろうと、交差点の信号機や赤信号で車が止まるなど、あるオブジェクトの状態変化が他のオブジェクトの状態変化を引き起こすというような問題に遭遇することがよくあります。が点灯し、緑色のライトが点灯している場合、車は走行し、ソフトウェアのボタンをクリックすると、ウィンドウがポップアップします。これらのオブジェクト間には依存関係があります. オブジェクトの動作はそれに依存する他のオブジェクトの反応を引き起こします. オブジェクト間の依存関係をより適切に記述するために, 新しい動作設計パターンを学ぶ必要があります. オブザーバーパターン.ソフトウェアの設計と開発で最も頻繁に使用される設計パターンの 1 つです。

定義のアイデア: オブジェクト間の 1 対多の依存関係を定義して、オブジェクトの状態が変化するたびに、他の関連オブジェクトに通知され、自動的に更新されるようにします。

利点:

  1. プレゼンテーション層とデータロジック層の分離を実現し、安定したメッセージ更新配信メカニズムを定義
  2. オブザーバーモードはブロードキャスト通信をサポートし、観測対象は登録されたすべてのオブザーバーに通知を送信します。これにより、1 対多のシステム設計の難しさが簡素化されます。
  3. オブザーバー モードは、開閉原理の要件を満たしています。新しい特定のオブザーバーを追加しても、元のシステム コードを変更する必要はありません。

短所:

  1. 観測対象物に直接観測者と間接観測者が多数存在する場合、すべての観測者に通知するのに多くの時間がかかります。
  2. オブザーバーと観測ターゲットの間に循環依存関係がある場合、観測ターゲットはそれらの間の循環呼び出しをトリガーし、システムがクラッシュする可能性があります

該当するシナリオ:

  1. オブジェクトは、それらのオブジェクトが誰であるかを知らなくても、他のオブジェクトに通知する必要があります
  2. 1 つのオブジェクトが変更されると、1 つまたは複数の他のオブジェクトが変更されます。変更されるオブジェクトの数は不明であるため、オブジェクト間の結合が減少します。ケース: 3 人のヒーローが 1 つのモンスターと戦い、モンスターが死ぬと、すべてのヒーローに通知する必要があり
    ます。 、ヒーローが死亡した場合の通知は必要ありません。

コード:

//抽象的英雄
class AbstractOHero
{
    
    
public:
	virtual void Update() = 0;
};

class HeroA : public AbstractOHero
{
    
    
public:
	HeroA()
	{
    
    
		cout << "英雄A正在打怪兽" << endl;
	}
	virtual void Update()
	{
    
    
		cout << "英雄A停止打怪兽" << endl;
	}
};

class HeroB : public AbstractOHero
{
    
    
public:
	HeroB()
	{
    
    
		cout << "英雄B正在打怪兽" << endl;
	}
	virtual void Update()
	{
    
    
		cout << "英雄B停止打怪兽" << endl;
	}
};

class HeroC : public AbstractOHero
{
    
    
public:
	HeroC()
	{
    
    
		cout << "英雄C正在打怪兽" << endl;
	}
	virtual void Update()
	{
    
    
		cout << "英雄C停止打怪兽" << endl;
	}
};

//抽象的观察目标
class AbstractBoss
{
    
    
public:
	//添加观察者
	virtual void addHero(AbstractOHero* hero) = 0;
	//删除观察者
	virtual void deleteHero(AbstractOHero* hero) = 0;
	//通知观察者
	virtual void notify() = 0;
};

//具体的观察者 BossA
class BossA : public AbstractBoss
{
    
    
public:
	//添加观察者
	virtual void addHero(AbstractOHero* hero)
	{
    
    
		pHeroList.push_back(hero);
	}
	//删除观察者
	virtual void deleteHero(AbstractOHero* hero)
	{
    
    
		pHeroList.remove(hero);
	}
	//通知观察者
	virtual void notify()
	{
    
    
		for (const auto& e : pHeroList)
		{
    
    
			e->Update();
		}
	}
private:
	list<AbstractOHero*> pHeroList;
};

テスト:

void test()
{
    
    
	//创建观察者
	AbstractOHero* heroA = new HeroA();
	AbstractOHero* heroB = new HeroB();
	AbstractOHero* heroC = new HeroC();

	//创建观察目标
	AbstractBoss* bossA = new BossA();
	bossA->addHero(heroA);
	bossA->addHero(heroB);
	bossA->addHero(heroC);

	cout << "heroC挂了" << endl;
	bossA->deleteHero(heroC);

	cout << "Boss死了,通知其英雄" << endl;
	bossA->notify();

	delete heroA;
	delete heroB;
	delete heroC;
	delete bossA;
}

スクリーンショットを実行します。
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/qq_44443986/article/details/117556371
おすすめ