【C++】Observer(デザインパターン)

## Observerとは?
あるオブジェクトの状態が変化した際に、
**それに関連する他のオブジェクトに自動的に通知する**設計。
- 監視者と監視対象を**疎結合にできる**
- 新しい監視者を簡単に追加できるため、**拡張性が高くなる**

### C++
```C++:Observer.cpp
#include <iostream>
#include <vector>
#include <string>

#define STRINGIFY(x) #x

/// <summary>
/// 監視者の抽象クラス
/// </summary>
class Observer
{
public:
	/// <summary>
	/// コンストラクタ
	/// </summary>
	/// <param name="_subject">監視対象</param>
	Observer(class Subject* _subject)
	{
		subject = _subject;
	}
	/// <summary>
	/// デストラクタ
	/// </summary>
	virtual ~Observer() = default;

	virtual void Update() = 0;

	class Subject* subject; // 監視対象
};

/// <summary>
/// 監視対象の抽象クラス
/// </summary>
class Subject
{
public:
	/// <summary>
	/// コンストラクタ
	/// </summary>
	Subject()
		: observers(new std::vector<class Observer*>())
	{
		SetState(STRINGIFY(STATE::FINE));
	}
	/// <summary>
	/// デストラクタ
	/// </summary>
	virtual ~Subject()
	{
		// コンテナの中の監視者を削除
		observers->clear();

		// コンテナ自身も削除
		delete observers;
	}

	enum class STATE
	{
		FINE,	// 元気
		SOSO,	// 普通
		BAD,	// 悪い
	};

	/// <summary>
	/// 状態を取得する
	/// </summary>
	inline std::string GetState() { return state; }
	/// <summary>
	/// 状態の設定
	/// </summary>
	/// <param name="_state">新しい状態</param>
	inline void SetState(std::string _state)
	{
		state = _state;
		StateNotify();
	}

	/// <summary>
	/// 監視者の追加
	/// </summary>
	/// <param name="_observer">追加する監視者のポインタ</param>
	void Attach(class Observer* _observer)
	{
		observers->push_back(_observer);
	}
	/// <summary>
	/// 監視者の削除
	/// </summary>
	/// <param name="_observer">削除する監視者のポインタ</param>
	void Detach(class Observer* _observer)
	{
		observers->erase
		(
			remove
			(
				observers->begin(),
				observers->end(),
				_observer
			)
		);
	}

private:
	/// <summary>
	/// 状態の変化を通知する
	/// </summary>
	void StateNotify()
	{
		for (class Observer* observer : *observers)
		{
			observer->Update();
		}
	}

	std::vector<class Observer*>* observers; // 監視者
	std::string state;
};

/// <summary>
/// 状態の監視者
/// </summary>
class StateObserver
	: public Observer
{
public:
	/// <summary>
	/// コンストラクタ
	/// </summary>
	/// <param name="_subject">監視対象</param>
	StateObserver(class Subject* _subject)
	// 基底のコンストラクタはデフォルトしか呼ばれない
	// 自分でどのコンストラクタを呼ぶかを明言する
		: Observer(_subject)
	{
		// 監視者に自身を登録
		_subject->Attach(this);
	}
	/// <summary>
	/// デストラクタ
	/// </summary>
	virtual ~StateObserver()
	{
		subject->Detach(this);
	}

	/// <summary>
	/// 更新処理
	/// </summary>
	void Update() override
	{
		std::cout << "状態の監視者:" << subject->GetState() << std::endl;
	}
};

/// <summary>
/// 監視対象「プレイヤー」
/// </summary>
class Player
	: public Subject
{
public:
	/// <summary>
	/// コンストラクタ
	/// </summary>
	Player() = default;
	/// <summary>
	/// デストラクタ
	/// </summary>
	virtual ~Player() = default;
};

int main(void)
{
	//監視される対象を作成
	Player* player = new Player();

	//監視者の作成
	std::vector<Observer*> observers = { new StateObserver(player)/* , ・・・ Observerを継承したクラスを無制限で追加できる*/};

	std::cout << "状態が少し悪化" << std::endl;
	player->SetState(STRINGIFY(Player::STATE::SOSO));
	std::cout << "状態が悪化" << std::endl;
	player->SetState(STRINGIFY(Player::STATE::BAD));

	delete player;

	return 0;
}
```

### C#
```C#:Observer.cs
using System;
using System.Collections.Generic;

/// <summary>
/// 監視者の抽象クラス
/// </summary>
public abstract class Observer
{
    public Subject subject; // 監視対象

	/// <summary>
	/// コンストラクタ
	/// </summary>
	/// <param name="_subject">監視対象</param>
	public Observer(Subject _subject)
	{
		subject = _subject;
	}

	public abstract void Update();
}

/// <summary>
/// 監視対象の抽象クラス
/// </summary>
public abstract class Subject
{
	private List<Observer> observers = new List<Observer>(); // 監視者
	public enum STATE
	{
		FINE,   // 元気
		SOSO,   // 普通
		BAD,    // 悪い
	};
	private STATE state;

	/// <summary>
	/// 状態を取得する
	/// </summary>
	public STATE GetState { get { return state; } }
	/// <summary>
	/// 状態の設定
	/// </summary>
	/// <param name="_state">新しい状態</param>
	public STATE SetState
	{
		set
		{
			state = value;
			StateNotify();
		}
	}

	/// <summary>
	/// 状態の変化を通知する
	/// </summary>
	private void StateNotify()
	{
		foreach (Observer observer in observers)
		{
			observer.Update();
		}
	}

	/// <summary>
	/// 監視者の追加
	/// </summary>
	/// <param name="_observer">追加する監視者のポインタ</param>
	public void Attach(Observer _observer)
	{
		observers.Add(_observer);
	}
	/// <summary>
	/// 監視者の削除
	/// </summary>
	/// <param name="_observer">削除する監視者のポインタ</param>
	public void Detach(Observer _observer)
	{
		observers.Remove(_observer);
	}
}

/// <summary>
/// 状態の監視者
/// </summary>
class StateObserver : Observer
{
	/// <summary>
	/// コンストラクタ
	/// </summary>
	/// <param name="_subject">監視対象</param>
	public StateObserver(Subject _subject)
		// 基底のコンストラクタはデフォルトしか呼ばれない
		// 自分でどのコンストラクタを呼ぶかを明言する
		: base(_subject)

	{
		// 監視者に自身を登録
		_subject.Attach(this);
	}

	/// <summary>
	/// 更新処理
	/// </summary>
	public override void Update()
	{
		Console.WriteLine("状態の監視者:" + subject.GetState);
	}
}

/// <summary>
/// 監視対象「プレイヤー」
/// </summary>
public class Player : Subject
{
    /// <summary>
    /// コンストラクタ
    /// </summary>
    public Player() { SetState = STATE.FINE; }
};

class Program
{
	static void Main()
	{
		//監視される対象を作成
		Player player = new Player();

		//監視者の作成
		List<Observer> observers = new List<Observer> { new StateObserver(player)/* , ・・・ Observerを継承したクラスを無制限で追加できる*/ };

		Console.WriteLine("状態が少し悪化");
		player.SetState = Player.STATE.SOSO;
		Console.WriteLine("状態が悪化");
		player.SetState = Player.STATE.BAD;
	}
}
```