策略模式(Strategy Pattern)

算法与对象的耦合:
    对象可能经常需要使用多种不同的算法,但是如果变化频繁,会将类型变得脆弱...
           
动机:
    在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。
    如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?

意图:
    定义一系统的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
                                                                     --------《设计模式》GOF

      
适用性:
    1.许多相关的类仅仅是行为有异。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
    2.需要使用一个算法的不同变体。例如,你可能会定义一些反映不同的空间/时间权衡的算法。当这些变体实现为一个算法的类层次时[H087],可以使用策略模式。   
    3.算法使用客户不应该知道数据。可使用策略模式以避免暴露复杂的,与算法相关的数据结构。
    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对象,从而节省对象开销。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值