重構之職責鏈模式

職責鏈模式(Chain of Responsibility):使多個對象都有機會處理請求,從而避免請求的發送者和接收者的耦合關係。將這個對象練成一條鏈,並沿着這條鏈傳遞該請求,直到有一個對象處理它爲止。

應用場景:
商店老闆向一家三口推銷冰激凌,小孩可以決定是否購買價格爲10,數量爲1的冰激凌,爸爸可以決定是否購買價格區間爲10~100,數量區間爲大於一的冰激凌,媽媽可以決定是否購買價格區間爲大於100,數量區間爲大於1的冰激凌。
故而進行如下代碼的編寫

首先,來看一下沒有用職責鏈時,我們的代碼是這樣的:
//冰激凌
public class Ice_Cream
{
	//冰激凌的價格
	private int price;
	public int Price
	{
		get {return price;}
		set {price=value;}
	}
	//冰激凌的數量
	private int num;
	public int Num
	{
		get {return num;}
		set {num=value;}
	}
}
//決定者
public class people
{
//獲得結果
	public void GetResult(string Status,Ice_Cream ice)
	{
		if (Status=="Kid")
		{
			if(ice.Price<=10 && ice.Num==1)
			{
				Console.WriteLine("孩子可以買");
			}
			else
			{
				Console.WriteLine("孩子買不了,讓孩兒的爸爸買");
			}
		}
		if (Status=="Dad")
		{
			if (ice.Price>=10 && ice.Price<=100 && ice.Num>1)
			{
				Console.WriteLine("爸爸可以買");
			}
			else
			{
				Console.WriteLine("爸爸買不了,讓孩兒的媽媽買");
			}
		}
		if (Status=="Mom")
		{
			if (ice.Price>100 && ice.Num>1)
			{
				Console.WriteLine("媽媽可以買");
			}
			else
			{
				Console.WriteLine("乖,咱不買");
			}
		}
	}
}
public static void Main(string[] args)
{
	Ice_Cream ice=new Ice_cream();
	ice.Price="50";
	ice.Num="2";
	People kid=new People();
	People dad=new People();
	People mom=new People();
	kid.GetResult("kid",ice);
	dad.GetResult("Dad",ice);
	mom.GetResult("Mom",ice);
	Console.Read();
}
從上面的代碼中,我們可以看到,要想確定冰激凌價格和數量由誰可以決定是否購買,必須要不斷進行if判斷,在People類中,if分支太長,代碼設計不佳,此外三個決策者之間缺乏關聯,需要多次調用GetResult方法進行if判斷,效率低下。
因此,我們對上述代碼進行重構,利用職責鏈模式,將People類中的三個決策者關聯起來,進行層層遞進的查找。
//定義一個抽象類決策者
public class abstract People
{
	protected People successor;
	//設置繼承者
	public void Setsuperior(People successor)
	{
		this.successor=successor();
	}
	//定義一個獲取結果的抽象方法 
	public abstract void GetResult(Ice_Cream ice);
}
public class Kid:People
{
	//重寫抽象方法GetResult
	public override void GetResult(Ice_Cream)
	{
		if(ice.Price<=10 && ice.Num==1)
		{
			Console.WriteLine("孩子可以買");
		}
		else if (successor != null)
		{
			//轉到下一個更高的級別
			successor.GetResult(ice);
		}
	}
}
public class Dad:People
{
	public override void GetResult(Ice_Cream ice)
	{
		if (ice.Price>=10 && ice.Price<=100 && ice.Num>1)
		{
			Console.WriteLine("爸爸可以買");
		}
		else if (successor != null)
		{
			successor.GetResult(ice);
		}
	}
}
public class Mom:People
{
	public override void GetResult(Ice_Cream ice)
	{
		if (ice.Price>100 && ice.Num>1)
		{
			Console.WriteLine("媽媽可以買");
		}
		else if (successor != null)
		{
			successor.GetResult(ice);
		}
	}
}
pulic static void Main(string[] args)
{
	/*運用多態,將子類對象賦給父類變量
	*在編譯過程中,kid,dad,mom作爲父類變量身份存在
	*在運行過程中,kid,dad,mom調用子類自己的方法來實現
	*/
	People kid=new Kid();
	People dad=new Dad();
	People mom=new Mom();
	//設置下一個更高級別,孩子的下一位是父親,父親的下一位是母親
	kid.SetSuccessor(dad);
	dad.SetSuccessor(mom);
	Ice_Cream ice=new Ice_Cream();
	ice.Price="50";
	ice.Num="2";
	//從最小一級開始進行調用
	kid.GetResult(ice);
	Console.Read();
}

通過上面兩個例子的對比,是不是對職責鏈有了一個簡單的認識呢?

在之後我們的重構中,如果存在上下級關係的分層次的判斷,可以嘗試利用職責鏈設計模式去實現,可以使代碼封裝的更好,且有效的降低耦合度。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章