星期一, 5月 29, 2006

[設計模式]觀察者模式

//觀察者模式
using System;
using System.Collections;

namespace Observer
{
///
/// Class1 的摘要描述。
/// 主控台測試部分
///

class Client
{
///
/// 應用程式的主進入點。
///

[STAThread]
static void Pause()
{
Console.WriteLine("Press Enter To Continue....");
Console.ReadLine();
}

static void Main(string[] args)
{
//這是負責顯示正常模式的物件
ShowNormal normal;
//這是負責顯示特殊模式的物件
ShowSpecial special;
// 球員資料
PlayerData playerData=new PlayerData();
//現在我把球員資料給綁定到觀察者
normal =new ShowNormal(playerData);
//現在我把球員資料給綁定到另一個觀察者
special =new ShowSpecial(playerData);
//一但球員資料有所變更 就會通知之前綁定的觀察者 而依序顯示出來 如此可以鬆綁兩者之間的關係
//這就是整個模式的關鍵 許多GUI也是用這種方式實做 一個當作listener 一但有所變更 立刻通知所有人
//如此即可讓資料一次更新並做處理
playerData.SetData("王大蠻",100);
//移除其中一個觀察者也沒問題
normal.Destory();
Pause();
}
}

//觀察者介面
interface Observer
{
void Update(string name,int skill);
void Destory();
}
//把顯示的介面另外獨立出來 因為要爭對介面寫程式
interface Display
{
void Show();
}

//
//實作觀察者與顯示介面
//

//正常顯示
class ShowNormal:Observer,Display
{
private string playerName;
private int playerSkill;
private Subject subject;
//將資料綁定 表示說向他註冊 有變更通知我
public ShowNormal(Subject subject)
{
this.subject=subject;
this.subject.Add(this);
}
//資料一但有變動就會呼叫這個更新
public void Update(string name,int skill)
{
playerName=name;
playerSkill=skill;
//這放其他地方會更好
Show();
}
//看要對資料做什麼處理 這裡暫時以顯示取代
public void Show()
{
Console.WriteLine("我顯示正常格式");
Console.WriteLine("使用者名稱"+playerName);
Console.WriteLine("技能"+playerSkill);
Console.WriteLine("");
}
//表示不要再綁定了 解除註冊
public void Destory()
{
subject.Remove(this);
Console.WriteLine("我ShowNormal被移除了\n");
}
}

//特出顯示
class ShowSpecial:Observer,Display
{
private string playerName;
private int playerSkill;
private Subject subject;
public ShowSpecial(Subject subject)
{
this.subject=subject;
this.subject.Add(this);
}
public void Update(string name,int skill)
{
playerName=name;
playerSkill=skill;
Show();
}
public void Show()
{
Console.WriteLine("我顯示特殊格式");
Console.WriteLine("使用者名稱*****"+playerName+"*******");
Console.WriteLine("技能~~~~~~~"+playerSkill+"~~~~~~~");
Console.WriteLine("");
}
public void Destory()
{
subject.Remove(this);
Console.WriteLine("我ShowSpecial被移除了");
}
}

//主題的介面 也就是可觀察的observable
interface Subject
{
void Add(Object ob);
void Notify();
void Remove(Object ob);
};

//實作主題 假設是球員資料
class PlayerData:Subject
{
private string playerName;
private int playerSkill;
ArrayList data;
public PlayerData()
{
data=new ArrayList();
}
//別人註冊會呼叫這個
public void Add(Object ob)
{
data.Add(ob);
}
//有變更就通知大家
public void Notify()
{
for (int a=0;a< data.Count;a++)
{
Observer observer =(Observer)data[a];
observer.Update(playerName,playerSkill);
}
}
//哪個想被移除就呼叫這個
public void Remove(Object ob)
{
data.Remove(ob);
}
//資料變更的地方
public void SetData(string name,int skill)
{
playerName=name;
playerSkill=skill;
Notify();
}
}
}

沒有留言: