策略模式的用意是針對一組演算法,將每一個演算法封裝到具有共同介面的獨立的類中,從而使得它們可以相互替換。策略模式使得演算法可以在不影響到客戶端的情況下發生變化。策略模式是對演算法的包裝,是把使用演算法的責任和演算法本身分割開,委派給不同的對象管理。策略模式通常把一個系列的演算法包裝到一系列的策略類裡面,作為一個抽...
策略模式的用意是針對一組演算法,將每一個演算法封裝到具有共同介面的獨立的類中,從而使得它們可以相互替換。策略模式使得演算法可以在不影響到客戶端的情況下發生變化。
策略模式是對演算法的包裝,是把使用演算法的責任和演算法本身分割開,委派給不同的對象管理。策略模式通常把一個系列的演算法包裝到一系列的策略類裡面,作為一個抽象策略類的子類。用一句話來說,就是:"準備一組演算法,並將每一個演算法封裝起來,使得它們可以互換。"
模式涉及到三個角色:
1、環境(Context)角色:持有一個Strategy類的引用。
2、抽象策略(ICommunication)角色:這是一個抽象角色,通常由一個介面或抽象類實現。此角色給出所有的具體策略類所需的介面。
3、具體策略(Serial、Lan)角色:包裝了相關的演算法或行為。
直接看例子:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Timers; namespace Demo { public interface ICommunication { bool Send(object data); } public class Serial:ICommunication { public bool Send(object data) { Console.WriteLine("通過串口發送一個數據的演算法"); return true; } } public class Lan:ICommunication { public bool Send(object data) { Console.WriteLine("通過網口發送一個數據的演算法"); return true; } } public class Context { private ICommunication _communication; public void SetStrategy(ICommunication communication)//傳遞具體的策略 { this._communication = communication; } public bool Send(object data) { return this._communication.Send(data); } } class Program { static void Main(string[] args) { Console.WriteLine("請輸入通信類型:Lan、Serial"); string input = Console.ReadLine(); object data = new object(); Context ct = new Context(); if (input.Equals("Lan")) //通過客戶端的選擇,來確定具體用哪種通信演算法 { ct.SetStrategy(new Lan()); } else { ct.SetStrategy(new Serial()); } ct.Send(data); Console.ReadKey(); } } }
運行結果:
從上面的例子可以看出,Strategy與Factory模式很類似,但Factory在創建時改變對象,而Strategy模式可自由切換。
Strategy模式可用於封裝較差卻易於實現的解決方案,也可以封裝較好卻難以實現的解決方案。可首先實現較差卻易於實現的解決方案,,然後用這個較差方案進行測試,利用該模式可在後期實現較好的方案,且不必更改調用演算法的方案。
策略模式的缺點有:
1. 客戶端必須知道所有的策略類,並自行決定使用哪一個策略類。這就意味著客戶端必須理解這些演算法的區別,以便適時選擇恰當的演算法類。換言之,策略模式只適用於客戶端知道所有的演算法或行為的情況。
2. 策略模式造成很多的策略類。有時候可以通過把依賴於環境的狀態保存到客戶端裡面,而將策略類設計成可共用的,這樣策略類實例可以被不同客戶端使用。換言之,可以使用享元模式來減少對象的數量。