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. Omu.AwesomeMvc.dll 和Omu.ValueInjecter.dll 介绍

    AwesomeMvc 让你不写一行js实现下拉列表联动 AwesomeMvc是个开源项目,地址:http://awesome.codeplex.com/ Omu.AwesomeMvc.dll 和Omu ...

  2. [leetcode 17]Letter Combinations of a Phone Number

    1 题目: Given a digit string, return all possible letter combinations that the number could represent. ...

  3. SQL Server 内存数据库原理解析

    前言 关系型数据库发展至今,细节上以做足文章,在寻求自身突破发展的过程中,内存与分布式数据库是当下最流行的主题,这与性能及扩展性在大数据时代的需求交相辉映.SQL Server作为传统的数据库也在最新 ...

  4. Web Api 中返回JSON的正确做法

    在使用Web Api的时候,有时候只想返回JSON:实现这一功能有多种方法,本文提供两种方式,一种传统的,一种作者认为是正确的方法. JSON in Web API – the formatter b ...

  5. Debian修改ssh端口和禁止root远程登陆设置

    linux修改端口22vi /etc/ssh/sshd_config找到#port 22将前面的#去掉,然后修改端口 port 1234重启服务就OK了service sshd restart或/et ...

  6. 跟我一起学WCF(6)——深入解析服务契约[下篇]

    一.引言 在上一篇博文中,我们分析了如何在WCF中实现操作重载,其主要实现要点是服务端通过ServiceContract的Name属性来为操作定义一个别名来使操作名不一样,而在客户端是通过重写客户端代 ...

  7. 设计模式之美:Facade(外观)

    索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):用抽象类定义 Facade 而使子类对应于不同的子系统. 意图 为子系统中的一组接口提供一个一致的界面,Facade 模式定义了 ...

  8. Silverlight动态载入调用XAML资源

      以多语言为例子: ResourceDictionary resourceDictionary = new ResourceDictionary(); //新建资源集合 var culture = ...

  9. SQLSERVER--定期清理维护作业的历史记录

    刚删除一个数据库时,在清理数据库备份历史记录时,执行超过近10分钟还未完成,随时查了下,吓死宝宝啦,逻辑读操作竟然高达8000万次以上! 通过UI进行删除数据库时,会默认勾选上“删除数据库备份和还原历 ...

  10. SQLServer DBA 三十问(加强版)

    距离最初发布SQLServer DBA 三十问 已有一年多了,大家对其中的某些问题讨论比较激烈,要回答出来这些问题需要比较扎实的SQLServer 基础和一定的实际操作经验,如果你试着去回答其中的问题 ...