算法与对象的耦合:
    对象可能经常需要使用多种不同的算法,但是如果变化频繁,会将类型变得脆弱...
           
动机:
    在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码对象中,将会使对象变得异常复杂;而且有时候支持不使用的算法也是一个性能负担。
    如何在运行时根据需要透明地更改对象的算法?将算法与对象本身解耦,从而避免上述问题?
意图:
    定义一系统的算法,把它们一个个封装起来,并且使它们可相互替换。本模式使得算法可独立于使用它的客户而变化。
                                                                     --------《设计模式》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对象,从而节省对象开销。

策略模式(Strategy Pattern)相关推荐

  1. 8.6 GOF设计模式四: 策略模式… Strategy Pattern

    策略模式- Strategy Pattern  在POS系统中,有时需要实行价格优惠, 该如何处理?  对普通客户或新客户报全价  对老客户统一折扣5%  对大客户统一折扣10%  注:课件 ...

  2. 解读设计模式----策略模式(Strategy Pattern)

    一.模式概述      策略模式(Strategy Pattern)在外形上与状态模式很相似,但在意图上有些不同.其意图是使这些算法可以相互替换,并提供一种方法来选择最合适的算法.       在我应 ...

  3. 二十四种设计模式:策略模式(Strategy Pattern)

    策略模式(Strategy Pattern) 介绍 定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换.本模式使得算法的变化可独立于使用它的客户. 示例 有一个Message实体类,对它的操 ...

  4. 设计模式(一):“穿越火线”中的“策略模式”(Strategy Pattern)

    在前段时间呢陆陆续续的更新了一系列关于重构的文章.在重构我们既有的代码时,往往会用到设计模式.在之前重构系列的博客中,我们在重构时用到了"工厂模式"."策略模式" ...

  5. 设计模式实战-策略模式(Strategy Pattern)

    0 联系我 图片标题 1.Q群[Java开发技术交流]:jq.qq.com/?_wv=1027&a- 2.完整博客链接:www.shishusheng.com 3.知乎:www.zhihu.c ...

  6. 策略模式Strategy Pattern应用场景

    策略模式(Strategy Pattern)是指定义了算法家族.分别封装起来,让它们之间可以互相替换,此模式让算法的变化不会影响到使用算法的用户. 策略模式的应用场景 1.假如系统中有很多类,而他们的 ...

  7. 锈才学设计模式之 —— 策略模式(Strategy Pattern)

    锈才学设计模式之  -- 策略模式 策略模式:把功能提供者单独封装成类,使它们可以互相替换使用,让功能提供者独立于使用者(调用者). 说明: 在面向对象编程中,我们尽量将功能(类)设计成复用,以符合O ...

  8. 39策略模式(Strategy Pattern)

    算法与对象的耦合:     对象可能经常需要使用多种不同的算法,但是如果变化频繁,会将类型变得脆弱...              动机:     在软件构建过程中,某些对象使用的算法可能多种多样,经 ...

  9. 设计模式-策略模式(Strategy Pattern)

    Define a family of algorithms,encapsulate each one,and make them interchangeable(定义一组算法,将每个算法都封装起来,并 ...

最新文章

  1. Java对象的四种引用方式
  2. 从零开始学习docker(十三)Docker Compose--scale
  3. listview 刷新结束 监听_Flutter 开发从 0 到 1(四)ListView 下拉加载和加载更多
  4. (转)如何在maven的pom.xml中添加本地jar包
  5. 初学数模-MATLAB Quick Start! Part I
  6. 微信HOOK发送Emoji表情
  7. 基于单片机语音控制灯系统设计
  8. 终端使用sopcast例子
  9. 土豆运行linux,安装到土豆上的 Linux 是怎么个意思?
  10. Linux中不同文字颜色代表的含义
  11. IDEA 依赖自动导入,不用每次手动点击Load Maven Changes图标
  12. 硬核拆台!宏彦获水,一脸懵逼:百度李彦宏遭当众泼水,一开始肇事者就在全程直播!!
  13. 安卓AutoCompleteTextView的简单使用(搜索时弹出可选择项)
  14. c语言输出法雷序列,法雷(法里)序列 - osc_h0wb1wlt的个人空间 - OSCHINA - 中文开源技术交流社区...
  15. POJ - 3067
  16. Android Sandbox(沙箱)开源工具介绍
  17. Mac本子下安装Maven的插件
  18. matlab之列主元素高斯消去法
  19. XSS Challenges/刷题/Stage #4
  20. Win11上的清除ftp登录账号与密码

热门文章

  1. Spring中ref local与ref bean区别
  2. Android抽象布局——include、merge 、ViewStub
  3. socket的阻塞非阻塞方法在缓冲区的差别
  4. 互联网协议 — OSPF 开放式最短路径优先协议
  5. Kubernetes — 在 OpenStack 上使用 kubeadm 部署高可用集群
  6. C 语言编程 — Makefile
  7. Altium Designer铺铜时抠铜
  8. Servlet简介与Servlet和HttpServlet运行的流程
  9. SecureCRT错误:The client has
  10. 如何获取js对象的对象名