C# Tips


Observerパターン(C#風にeventとdelegateをつかう)


Observerパターンの実装をC#風にdelegateを使用して行った例です。
delegateを使うと、observerとobservableインターフェイスを使った例よりも少ないコードで記述することが出来ます。登録されたobserverの管理、Notify()、Update()がなくなります。ただし、欠点としては一見してobservableかどうかわからなくなってしまったことです。

Observerパターンとは、
1. あるクラスの値が変更された (observable class)
2. 別のクラスでその変更を認識したい (observer)
というときに使います。
GUIのプログラムなどによく用いられ、マウスが押されたときに特定のイベントを実行する、データが変更されたときにGUIの表示もアップデートする、などといった使われ方が一般的です。

Dataがobservable class(変更されたときに通知するクラス)、GUIがobserverクラス(通知を受けるクラス)になります。
DataのNameプロパティが変更されたときにChangedEventHandlerに対してイベントを起こします(通知)。
通知を受けたChangedEventHandlerはそこに登録されている関数に向けて通知を行います。ここでは、gui.updateという関数が登録されていますので、その関数が呼ばれます。誰が呼び出したかがわかるようにここでは引数にobject senderを使用しています。
using System;

namespace Observer
{
	//メインクラスです
	public class Observer
	{
		public static void Main()
		{
			GUI gui = new GUI();
			Data data = new Data();

			//通知を受ける関数の登録
			ChangedEventHandler eventHandler = new ChangedEventHandler(gui.update);

			data.Changed += eventHandler;

			//DataのNameを変更してみる
			for(int i=0; i < 10; i++)
			{
				if(i != 0)
				{
					data.Name +=  ",";
				}

				data.Name += i.ToString();
			}

			data.Changed -= eventHandler;
		}

	}

	//イベントに対してdelegateを宣言するt
	public delegate void ChangedEventHandler(object sender);

	//observable class
	//変更されたときに通知します
	public class Data
	{
		//declare the event using the delegate
		public event ChangedEventHandler Changed;

		private string name = "";
       
		public string Name
		{
			get
			{
				return name;
			}
			set
			{
				this.name = value;

				//データが変更されたときに通知することをここで集中管理
				OnChange(this);
			}
		}

		private void OnChange(object sender)
		{
			if(Changed != null)
			{	
				Changed(sender);
			}
		}
	}

	//observer class
	//変更の通知を受けます
	public class GUI
	{
		public void update(object sender)
		{
			Console.WriteLine(((Data)sender).Name);
		}
	}
}


目次に戻る
Copyright(c) 2008 WoodenSoldier Software