索引

别名

  • Policy

意图

定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。使得算法可独立于使用它的客户而变化。

Define a family of algorithms, encapsulate each one, and make them interchangeable.

Strategy lets the algorithm vary independently from clients that use it.

结构

参与者

Strategy

  • 定义所有支持的算法的公共接口。Context 使用这个接口来调用 ConcreteStrategy 定义的算法。

ConcreteStrategy

  • 实现 Strategy 接口和具体算法。

Context

  • 用一个 ConcreteStrategy 对象来配置。
  • 维护一个对 Strategy 对象的引用。
  • 可定义一个接口来让 Strategy 访问它的数据。

适用性

在以下情况下可以使用 Strategy 模式:

  • 许多相关的类仅仅是行为有异。Strategy 提供了一种用多个行为中的一个行为来配置一个类的方法。
  • 需要使用一个算法的不同变体。
  • 算法使用客户不应该知道的数据。
  • 一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关条件分支移入它们各自的 Strategy 类中以代替。

缺点

  • 客户必须了解不同的 Strategy。要选择合适的 Strategy 就必须知道这些 Strategy 有何不同。
  • Strategy 和 Context 之间的通信开销。Context 可能创建一些 ConcreteStrategy 不使用的参数。
  • 增加了对象的数目。

效果

  • 相关算法系列。
  • 一个替代继承的方法。
  • 消除了一些条件语句。
  • 实现的选择。相同行为的不同实现。

相关模式

  • 使用 Flyweight 模式实现 Strategy。

实现

实现方式(一):使用不同的 Strategy 处理内部状态。

Strategy 和 Context 接口必须使得 ConcreteStrategy 能够有效的访问它所需要的 Context 中的任何数据。

一种办法是让 Context 将数据放在参数中传递给 Strategy 操作。这使得 Strategy 和 Context 解耦。

但另一方面,Context 可能发送一些 Strategy 不需要的数据。

另一种办法是让 Context 将自身作为一个参数传递给 Strategy,该 Strategy 再显式地向该 Context 请求数据。

或者 Strategy 可以直接保存对 Context 的引用。

这种情况下,Strategy 可以请求到它需要的数据。但这使得 Strategy 和 Context 更紧密的耦合在一起。

 namespace StrategyPattern.Implementation1
{
public abstract class Strategy
{
public abstract void AlgorithmInterface(string state);
} public class ConcreteStrategyA : Strategy
{
public override void AlgorithmInterface(string state)
{
Console.WriteLine("Use Concrete Strategy A to handle " + state);
}
} public class ConcreteStrategyB : Strategy
{
public override void AlgorithmInterface(string state)
{
Console.WriteLine("Use Concrete Strategy B to handle " + state);
}
} public class Context
{
private Strategy _strategy; public void SetStrategy(Strategy strategy)
{
_strategy = strategy;
} public string State { get; set; } public void ContextInterface()
{
_strategy.AlgorithmInterface(State);
}
} public class Client
{
public void TestCase1()
{
var context = new Context();
context.State = "Hello World"; context.SetStrategy(new ConcreteStrategyA());
context.ContextInterface(); context.SetStrategy(new ConcreteStrategyB());
context.ContextInterface();
}
}
}

设计模式之美》为 Dennis Gao 发布于博客园的系列文章,任何未经作者本人同意的人为或爬虫转载均为耍流氓。

设计模式之美:Strategy(策略)的更多相关文章

  1. 设计模式22:Strategy 策略模式(行为型模式)

    Strategy 策略模式(行为型模式) 动机(Motivation) 在软件构建过程中,某些对象使用的算法可能多种多样,经常改变,如果将这些算法都编码到对象中,将会使对象变得异常复杂:而且有时候支持 ...

  2. Java的设计模式----strategy(策略模式)

    设计模式: 一个程序员对设计模式的理解: “不懂”为什么要把很简单的东西搞得那么复杂.后来随着软件开发经验的增加才开始明白我所看到的“复杂”恰恰就是设计模式的精髓所在,我所理解的“简单”就是一把钥匙开 ...

  3. 设计模式(21)--Strategy(策略模式)--行为型

    作者QQ:1095737364    QQ群:123300273     欢迎加入! 1.模式定义: 策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而 ...

  4. Java设计模式(18)策略模式(Strategy模式)

    Strategy是属于设计模式中 对象行为型模式,主要是定义一系列的算法,把这些算法一个个封装成单独的类. Stratrgy应用比较广泛,比如,公司经营业务变化图,可能有两种实现方式,一个是线条曲线, ...

  5. 一天一个设计模式——Strategy策略模式

    一.模式说明 策略模式比较好理解,就是将程序中用到的算法整体的拿出来,并有多个不同版本的算法实现,在程序运行阶段,动态的决定使用哪个算法来解决问题. 举个实际的例子:排序算法的问题,假如我们的程序中需 ...

  6. C++设计模式-Strategy策略模式

    Strategy策略模式作用:定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. UML图: Strategy模式将逻辑(算法)封装到一个类(Cont ...

  7. Strategy策略设计模式

    1.策略模式和状态模式的区别和联系(本部分转载自:http://letscoding.cn/java%E4%B8%AD%EF%BC%8C%E7%8A%B6%E6%80%81%E6%A8%A1%E5%B ...

  8. JAVA设计模式——(2)策略模式

    定义 定义一种算法,将每个算法都封装起来,并且使它们之间可以互换.是一种行为类模式. 举例 为了通俗易懂,我们拿各国的税率计算来举例子: 假设当前我们的程序只能支持计算中国和美国的税率: public ...

  9. 设计模式之美:Null Object(空对象)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Null Object 的示例实现. 意图 通过对缺失对象的封装,以提供默认无任何行为的对象替代品. Encapsulate t ...

随机推荐

  1. CSS浏览器兼容问题总结

    为什么会出现浏览器兼容问题? 由于各大主流浏览器是不同的厂家开发的,所以使用的核心也不相同,架构代码很难重合,就会产生各种各样的bug. IE6中常见的css解析bug 1)默认高度(IE6)部分块元 ...

  2. hibernate存储过程 3

              hibernate存储过程 User.hbm.xml文件的内容如下: <?xml version="1.0"?> <!DOCTYPE hibe ...

  3. 解压版MySQL5.7.1x的安装与配置

    解压版MySQL5.7.1x的安装与配置 MySQL安装文件分为两种,一种是msi格式的,一种是zip格式的.如果是msi格式的可以直接点击安装,按照它给出的安装提示进行安装(相信大家的英文可以看懂英 ...

  4. javascript中关于深复制与浅复制的问题

    在javascript中,变量的类型分为基本类型和引用类型. 对于基本类型的变量来说,值的复制以及作为函数参数实参传递的过程都是值的复制传递,换句话说,是会在内存中开辟出一个新空间用于存放新的值的.这 ...

  5. Android自定义View的实现方法,带你一步步深入了解View(四)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17357967 不知不觉中,带你一步步深入了解View系列的文章已经写到第四篇了,回 ...

  6. Java编程中“为了性能”尽量要做到的一些地方

    最近的机器内存又爆满了,除了新增机器内存外,还应该好好review一下我们的代码,有很多代码编写过于随意化,这些不好的习惯或对程序语言的不了解是应该好好打压打压了. 下面是参考网络资源总结的一些在Ja ...

  7. JS 获取FileUpload1控件地址

    function openList() { //判断浏览器类型 var isIE = (document.all) ? true : false; ); ); ); var path = " ...

  8. 1.linux服务器的性能分析与优化

    [教程主题]:1.linux服务器的性能分析与优化 [课程录制]: 创E [主要内容] [1]影响Linux服务器性能的因素 操作系统级 CPU 目前大部分CPU在同一时间只能运行一个线程,超线程的处 ...

  9. zabbix server配置文件

    这样的错误日志,并且在web端也没有画出图来. 解决方法: ①编辑zabbix服务器端的配置文件/etc/zabbix/zabbix_server.conf找到"Timeout"把 ...

  10. 三种Scriptlet总结

    什么是Scriptlet? 在JSP中,Scriptlet称为脚本小程序,所欲嵌套在HTML代码中的Java程序都必须使用Scriptlet标记出来. 第一种:<% %> 在此Script ...