星期三, 5月 31, 2006

[設計模式]狀態模式

//狀態模式
using System;

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

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

[STAThread]
static void Main(string[] args)
{
//建立主遊戲
MainGame main=new MainGame();
while(true)
{
//繪圖
main.FrameRender();
//運算
main.FrameMove();
}
}
}

//主狀態介面
interface MajorState
{
//每個狀態都有有兩個動作
//負責運算
void FrameMove();
//負責繪圖
void FrameRender();
}

//開始實做狀態介面

//建立狀態
class MS_Create: MajorState
{
//每個都有一個mainGame物件
MainGame mainGame;
public MS_Create(MainGame mainGame){this.mainGame=mainGame;}
public void FrameMove()
{
//改變狀態 取得mainGame的中的下個狀態然後再設給mainGame
mainGame.SetCurrentState(mainGame.GetMainMenuState());
}
public void FrameRender()
{
Console.WriteLine("程式被建立\n");
}
};

//下面如法泡製
//主選單狀態
class MS_MainMenu: MajorState
{
MainGame mainGame;
public MS_MainMenu(MainGame mainGame){this.mainGame=mainGame;}
public void FrameMove()
{
Console.ReadLine();
mainGame.SetCurrentState(mainGame.GetMainGameState());
}

public void FrameRender()
{
Console.WriteLine("我在主選單\n");
}
};
//主遊戲狀態
class MS_MainGame: MajorState
{
MainGame mainGame;
public MS_MainGame(MainGame mainGame){this.mainGame=mainGame;}
public void FrameMove()
{
Console.ReadLine();
mainGame.SetCurrentState(mainGame.GetDestoryState());
}

public void FrameRender()
{
Console.WriteLine("我在主遊戲\n");
}
};

//摧毀狀態
class MS_Destory: MajorState
{
MainGame mainGame;
public MS_Destory(MainGame mainGame){this.mainGame=mainGame;}

public void FrameMove()
{
Console.WriteLine("Press Enter To Continue....\n");
Console.ReadLine();
Environment.Exit(0);

}
public void FrameRender()
{
Console.WriteLine("摧毀遊戲\n");
Console.ReadLine();

}
};

//主遊戲的類別
class MainGame
{
//先宣告所有狀態類別
private MajorState ms_Create;
private MajorState ms_MainMenu;
private MajorState ms_MainGame;
private MajorState ms_Destory;
//記錄目前的狀態
private MajorState currentState;
public MainGame()
{
//把自己跟狀態綁定
ms_Create=new MS_Create(this);
ms_MainMenu=new MS_MainMenu(this);
ms_MainGame=new MS_MainGame(this);
ms_Destory=new MS_Destory(this);
//一開始預設就是先建立狀態
currentState=ms_Create;
}
//一旦呼叫FrameMove就執行當時狀態的FrameMove
public void FrameMove()
{
currentState.FrameMove();
}
//一旦呼叫FrameRender就執行當時狀態的FrameRender
public void FrameRender()
{
currentState.FrameRender();
}
//取得各個狀態
public MajorState GetCreateState(){return ms_Create;}
public MajorState GetMainMenuState(){return ms_MainMenu;}
public MajorState GetMainGameState(){return ms_MainGame;}
public MajorState GetDestoryState(){return ms_Destory;}
//設定狀態
public void SetCurrentState(MajorState state){currentState=state;}

};
}

星期一, 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();
}
}
}

星期五, 5月 26, 2006

[設計模式]策略模式

//策略模式
using System;

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

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

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

static void Main(string[] args)
{
//建立一位打者叫做barryBonds
BaseballPlayer player1=new BarryBonds();
//可以改變它的行為模式
//player1.SetSwingPosture(new NormalPosture());
//揮棒
player1.Swing();
Pause();
}
}
//抽象類別 野手類別
abstract class BaseballPlayer
{
protected SwingPosture posture;
public void Swing()
{
posture.Swing();
}
public void SetSwingPosture(SwingPosture posture)
{
this.posture=posture;
}
}
//繼承類別 有個叫做barrybonds的野手
class BarryBonds:BaseballPlayer
{
//設定他的打擊姿勢
public BarryBonds()
{
posture=new StarPosture();
}
};

//
//把容易變動的部份抽出來 利如揮棒姿勢 許多人都不一樣 但是也有一樣的 所以另外封裝
//

//揮棒姿勢的介面
interface SwingPosture
{
void Swing();
};

//實作揮棒姿勢 這是正常的揮棒姿勢
class NormalPosture:SwingPosture
{

#region SwingPosture 成員

public void Swing()
{
Console.WriteLine("我用正常姿勢揮棒");
}

#endregion

}
// 這是明星的揮棒姿勢
class StarPosture:SwingPosture
{

#region SwingPosture 成員

public void Swing()
{
Console.WriteLine("我用明星姿勢揮棒");
}

#endregion

}

}