1、策略模式和状态模式的区别和联系(本部分转载自:http://letscoding.cn/java%E4%B8%AD%EF%BC%8C%E7%8A%B6%E6%80%81%E6%A8%A1%E5%BC%8F%E5%92%8C%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F%E7%9A%84%E5%8C%BA%E5%88%AB/)

策略模式通过封装一组相关算法,为Client提供运行时的灵活性。Client可以在运行时,选择任一算法,而不改变使用算法的Context。一些流行的策略模式的例子是写那些使用算法的代码,例如加密算法、压缩算法、排序算法。另一方面,状态模式允许对象,在不同的状态拥有不同的行为。因为现实世界中的对象通常都是有状态的,所以它们在不同状态,行为也不一样。例如,VM(自动售货机)只在hasCoin状态才给你吐商品;你不投币,它是不会吐的。现在你可以清楚的看出它们的不同之处了:它们的意图是不同的。状态模式帮助对象管理状态,而策略模式允许Client选择不同的行为。

另一个不那么容易能看出来的区别是:是谁促使了行为的改变。策略模式中,是Client提供了不同的策略给Context;状态模式中,状态转移由Context或State自己管理。另外,如果你在State中管理状态转移,那么它必须持有Context的引用。例如,在VM的例子中,State对象需要调用VM的setState()方法去改变它的状态。另一方面,Strategy从不持有Context的引用,是Client把所选择的Strategy传递给Context。由于状态模式和策略模式的区别,是流行的Java设计原则类面试题之一,我们将会在本文探讨在Java中,状态模式和策略模式的异同,这可以加深你对它们的理解。

相似之处

如果你看看状态模式和策略模式的UML图,就会发现它们的结构非常相似。使用State对象改变自己行为的对象被称为Context对象;相似的,使用Strategy对象改变自己行为的对象叫Context对象。记住,Client和Context打交道。在状态模式中,Context把方法调用委托给当前的状态对象,而在策略模式中,Context使用的Strategy对象,是被当做参数传递过来的,或在Context对象被创建时就被提供的。

让我们来看看它们之间更多的相似之处:

  1. 添加新的状态或策略都很容易,而且不需要修改使用它们的Context对象。
  2. 它们都让你的代码符合OCP原则。在状态模式和策略模式中,Context对象对修改是关闭的,添加新的状态或策略,都不需要修改Context。
  3. 正如状态模式中的Context会有初始状态一样,策略模式同样有默认策略。
  4. 状态模式以不同的状态封装不同的行为,而策略模式以不同的策略封装不同的行为。
  5. 它们都依赖子类去实现相关行为。

不同之处

现在我们知道,状态模式和策略模式的结构是相似的,但它们的意图不同。让我们重温一下它们的主要不同之处:

  1. 策略模式封装了一组相关算法,它允许Client在运行时使用可互换的行为;状态模式帮助一个类在不同的状态显示不同的行为。
  2. 状态模式封装了对象的状态,而策略模式封装算法或策略。因为状态是跟对象密切相关的,它不能被重用;而通过从Context中分离出策略或算法,我们可以重用它们。
  3. 在状态模式中,每个状态通过持有Context的引用,来实现状态转移;但是每个策略都不持有Context的引用,它们只是被Context使用。
  4. 策略实现可以作为参数传递给使用它的对象,例如Collections.sort(),它的参数包含一个Comparator策略。另一方面,状态是Context对象自己的一部分,随着时间的推移,Context对象从一个状态转移到另一个状态。
  5. 虽然它们都符合OCP原则,策略模式也符合SRP原则(单一职责原则),因为每个策略都封装自己的算法,且不依赖其他策略。一个策略的改变,并不会导致其他策略的变化。
  6. 另一个理论上的不同:策略模式定义了对象“怎么做”的部分。例如,排序对象怎么对数据排序。状态模式定义了对象“是什么”和“什么时候做”的部分。例如,对象处于什么状态,什么时候处在某个特定的状态。
  7. 状态模式中很好的定义了状态转移的次序;而策略模式并无此需要:Client可以自由的选择任何策略。
  8. 一些常见的策略模式的例子是封装算法,例如排序算法,加密算法或者压缩算法。如果你看到你的代码需要使用不同类型的相关算法,那么考虑使用策略模式吧。而识别何时使用状态模式是很简单的:如果你需要管理状态和状态转移,但不想使用大量嵌套的条件语句,那么就是它了。
  9. 最后但最重要的一个不同之处是,策略的改变由Client完成;而状态的改变,由Context或状态自己。

本段译自:Difference between State and Strategy Design Pattern in Java

2、URL图下载地址(astah/jude):http://pan.baidu.com/s/1hqy0c88

3、示例

公共策略规范接口

 package com.xinye.test.strategy;
/**
* 策略通用接口
* @author xinye
*
*/
public interface IStrategy {
public void strategy();
}

默认策略

 package com.xinye.test.strategy;
/**
* 默认Strategy
* @author xinye
*
*/
public class NormalStrategy implements IStrategy { @Override
public void strategy() {
System.out.println(getClass().getSimpleName() + " strategy()");
} }

第一种策略

package com.xinye.test.strategy;
/**
* 第一种Strategy
* @author xinye
*
*/
public class FirstStrategy implements IStrategy { @Override
public void strategy() {
System.out.println(getClass().getSimpleName() + " strategy()");
} }

第二种策略

 package com.xinye.test.strategy;
/**
* 第二种Strategy
* @author xinye
*
*/
public class SecondStrategy implements IStrategy { @Override
public void strategy() {
System.out.println(getClass().getSimpleName() + " strategy()");
} }

策略Context

 package com.xinye.test.strategy;
/**
* 策略模式Context
* @author xinye
*
*/
public class Context { private IStrategy strategy = new NormalStrategy();
/**
* 需要客户端把策略传递过来
* @param s
*/
public void exec(IStrategy s){
strategy = s;
strategy.strategy();
}
}

客户端代码

package com.xinye.test.strategy;
/**
* 客户端代码
* @author xinye
*
*/
public class Client {
public static void main(String[] args) { Context context = new Context();
// 传递给Context特定的策略
context.exec(new NormalStrategy());
// 传递给Context特定的策略
context.exec(new FirstStrategy());
// 传递给Context特定的策略
context.exec(new SecondStrategy());
}
}

执行结果
NormalStrategy strategy()
FirstStrategy strategy()
SecondStrategy strategy()

Strategy策略设计模式的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. Java设计模式之策略设计模式

    1.什么是-策略设计模式 在软件开发中常常遇到这种情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Ha ...

  7. java策略设计模式

    1.概述 策略模式定义了一系列的算法,并将每一个算法封装起来,而且使他们可以相互替换,让算法独立于使用它的客户而独立变化. 其实不要被晦涩难懂的定义所迷惑,策略设计模式实际上就是定义一个接口,只要实现 ...

  8. JAVA学习笔记--策略设计模式与适配器模式

    一.策略设计模式 创建一个能够根据所传递对象的不同而具有不同行为的方法被称为策略设计模式:这类方法包含所要执行的算法中固定不变的部分,而“策略”包含变化的部分.策略就是传递进去的参数对象,它包含要执行 ...

  9. 10、Strategy 策略模式 整体地替换算法 行为型模式

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

随机推荐

  1. PHP程序设计经典300例

    不知道怎么转载,原文源自:http://bbs.php100.com/u-htm-uid-330857.html 来自:php100钟泽锋 第一例<?php $s_html="< ...

  2. Mandelbrot和Julia

    概述 mandelbrot julia Mandelbrot 对全体复数z,满足xn+1 =  xn2 + z从x0 = 0起,|x|随n值增加不趋于无穷大,则z属于Mandelbrot集 代码 #i ...

  3. linux-7 man 命令

    man  命令的分类 man 命令 代码 代表内容 普通命令 内核调用的函数与工具 常见的函数与函数库 设备文件的说明 配置文件 游戏 惯例与协议 管理员可使用的命令 内核相关的文件 一般来讲帮助文档 ...

  4. 10 个超酷的加载中的 Gif 动画

    #1: Calming cat loading gif #2: Stylish loading gif #3: Shape changing loading gif #4: Loading gif f ...

  5. 设计模式之美:Flyweight(享元)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):使用 FlyweightFactory 管理 Flyweight 对象. 意图 运用共享技术有效地支持大量细粒度的对象. Use ...

  6. jQuery Mobile + HTML5

    最近项目需要,需要构建一个适合手持设备访问的站点,作者从网上查阅了一些资料,本文就是基于此而来. 首先下载jQuery Mobile http://jquerymobile.com/,选择稳定版即可. ...

  7. ASP.NET MVC简单编程之(二)经典路由篇

    话题:请求从路由开始 在实际的ASP.NET MVC开发中,URL访问规则----路由的定义是非常重要的.因为任何一个请求都离不开路由.理解它,我们将能理解MVC处理请求的整个过程,灵活地定义系统各种 ...

  8. paip.提升性能3倍--使用栈跟VirtualAlloc代替堆的使用.

    paip.提升性能3倍--使用栈跟VirtualAlloc代替堆的使用. #----为什么要设计堆栈,它有什么独特的用途? 为了性能 ....  堆比栈的性能 也有的说法为了编程容易...这个是错误的 ...

  9. paip.函数式编程方法概述以及总结

    paip.函数式编程方法概述以及总结 1     函数式编程:函数式风格..很多命令式语言里支持函数式编程风格 1.1      起源 (图灵机,Lisp机器, 神经网络计算机) 1.2      函 ...

  10. tab切换的两种方法

    方法一.主要使用了传递参数的思想,把循环变量不能使用转换了一下<!DOCTYPE html><html lang="en"><head> < ...