39策略模式(Strategy Pattern)
算法與對象的耦合:
??? 對象可能經常需要使用多種不同的算法,但是如果變化頻繁,會將類型變得脆弱...
? ? ? ?? ???
動機:
??? 在軟件構建過程中,某些對象使用的算法可能多種多樣,經常改變,如果將這些算法都編碼對象中,將會使對象變得異常復雜;而且有時候支持不使用的算法也是一個性能負擔。
??? 如何在運行時根據需要透明地更改對象的算法?將算法與對象本身解耦,從而避免上述問題?
意圖:
??? 定義一系統的算法,把它們一個個封裝起來,并且使它們可相互替換。本模式使得算法可獨立于使用它的客戶而變化。
???????????????????????????????????????????????????????????????????? --------《設計模式》GOF
??? ???
適用性:
??? 1.許多相關的類僅僅是行為有異?!安呗浴碧峁┝艘环N用多個行為中的一個行為來配置一個類的方法。
??? 2.需要使用一個算法的不同變體。例如,你可能會定義一些反映不同的空間/時間權衡的算法。當這些變體實現為一個算法的類層次時[H087],可以使用策略模式。????
??? 3.算法使用客戶不應該知道數據??墒褂貌呗阅J揭员苊獗┞稄碗s的,與算法相關的數據結構。
??? 4.一個類定義了多種行為,并且這些行為在這個類的操作中以多個條件語句的形式出現。將相關的條件分支移入它們各自的Strategy類中以代替這些條件語句。
代碼實現:
????
1???enum?SortType
2?????{
3?????????QuickSort,
4?????????ShellSort,
5?????????MergeSort,
6?????}
?
?1?????class?Sort
?2?????{
?3?????????public?void?SortList(SortType?s)
?4?????????{
?5?????????????if?(s?==?SortType.QuickSort)
?6?????????????{
?7?????????????????ProcessA();
?8?????????????}
?9?????????????else?if?(s?==?SortType.ShellSort)
10?????????????{
11?????????????????ProcessB();
12?????????????}
13?????????????else?if?(s?==?SortType.MergeSort)
14?????????????{
15?????????????????ProcessC();
16?????????????}
17?????????????Console.WriteLine();
18?????????}
19?
20?????????protected?void?ProcessA()
21?????????{
22?????????????Console.WriteLine("QuickSort?List");
23?????????}
24?????????protected?void?ProcessB()
25?????????{
26?????????????Console.WriteLine("ShellSort?List");
27?????????}
28?????????protected?void?ProcessC()
29?????????{
30?????????????Console.WriteLine("MergeSort?List");
31?????????}
32?????}
客戶端調用:
?1?????class?Test
?2?????{
?3????????????public?static?void?Main()
?4????????????{
?5????????????????Sort?sort?=?new?Sort();
?6????????????????sort.SortList(SortType.QuickSort);
?7????????????????sort.SortList(SortType.ShellSort);
?8????????????????sort.SortList(SortType.MergeSort);
?9????????????}
10?????}
??? 由此可見,由于客戶端新增調用方式的選擇,就會修改SortType及Sort里的判斷語句。在類Sort中會增加if語句的判斷,用敏捷軟件開發的語言說,你應該聞到了代碼的臭味道了,也就是設計模式中說的存在了變化的地方。
?? 重構以上代碼,增加一層中間層來處理變化。類結構如下:?
?????????????????
1????//Stategy??表達抽象算法
2????abstract??class?SortStrategy
3?????{
4????????public?abstract?void?Sort(ArrayList?list);
5?????}
?
?1????//ConcreteStrategy
?2?????class?ShellSort?:SortStrategy
?3?????{
?4?????????public?override?void?Sort(System.Collections.ArrayList?list)
?5?????????{
?6??????????????????list.Sort();?//no-implement
?7?????????????????Console.WriteLine("ShellSorted?List");
?8?????????????
?9?????????}
10?????}
?
1???//ConcreteStrategy
2?????class?MergeSort?:SortStrategy
3?????{
4?????????public?override?void?Sort(System.Collections.ArrayList?list)
5?????????{
6?????????????list.Sort();?//no-implement
7?????????????Console.WriteLine("MergeSort?List?");
8?????????}
9?????}
1????//ConcreteStrategy
2?????class?QuickSort?:SortStrategy
3?????{
4?????????public?override?void?Sort(System.Collections.ArrayList?list)
5?????????{
6?????????????list.Sort();?//Default?is?Quicksort
7?????????????Console.WriteLine("QuickSorted?List");
8?????????}
9?????}
?
?1?????//Context
?2?????class?SortdList
?3?????{
?4?????????private?ArrayList?list?=?new?ArrayList();
?5?????????private?SortStrategy?sortstrategy;??//對象組合
?6?????????public?void?SetSortStrategy(SortStrategy?sortstrategy)
?7?????????{
?8?????????????this.sortstrategy?=?sortstrategy;
?9?????????}
10?????????public?void?Add(string?name)
11?????????{
12?????????????list.Add(name);
13?????????}
14?????????public?void?Sort()
15?????????{
16?????????????sortstrategy.Sort(list);
17?????????????//Display?results?
18?????????????foreach?(string?name?in?list)
19?????????????{
20?????????????????Console.WriteLine("?"?+?name);
21?????????????}
22?????????????Console.WriteLine();
23?????????}
24?????}
客戶端代碼如下:
?1????class?Program
?2?????{
?3?????????static?void?Main(string[]?args)
?4?????????{
?5?????????????//Two?contexts?following?different?strategies?
?6?????????????SortdList?studentRecords?=?new?SortdList();
?7?
?8?????????????studentRecords.Add("Satu");
?9?????????????studentRecords.Add("Jim");
10?????????????studentRecords.Add("Palo");
11?????????????studentRecords.Add("Terry");
12?????????????studentRecords.Add("Annaro");
13?
14?????????????studentRecords.SetSortStrategy(new?QuickSort());
15?????????????studentRecords.Sort();
16?
17?????????????studentRecords.SetSortStrategy(new?ShellSort());
18?????????????studentRecords.Sort();
19?
20?????????????studentRecords.SetSortStrategy(new?MergeSort());
21?????????????studentRecords.Sort();
22?
23?????????????Console.Read();
24?????????}
25?????}
由此可見,更好地滿足開放封閉原則。
Strategy模式的幾個要點:
??? 1.Strategy及其子類為組件提供了一系列可重用的算法,從而可以使得類型在運行時方便地根據需要在各個算法之間進行切換。所謂封裝算法,支持算法的變化。
??? 2.Strategy模式提供了用條件判斷語句以外的另一種選擇,消除條件判斷語句,就是在解耦合。含有許多條件判斷語句的代碼通常都需要Strategy模式。
??? 3.與State類似,如果Strategy對象沒有實例變量,那么各個上下文可以共享同一個Strategy對象,從而節省對象開銷。
總結
以上是生活随笔為你收集整理的39策略模式(Strategy Pattern)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 海王娘娘哭一场 巨亏一千万
- 下一篇: 今天是神舟十二号发射一周年!官方晒航天员