一、策略模式和状态模式的区别和联系(本部分转载自: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/)html
策略模式经过封装一组相关算法,为Client提供运行时的灵活性。Client能够在运行时,选择任一算法,而不改变使用算法的Context。一些流行的策略模式的例子是写那些使用算法的代码,例如加密算法、压缩算法、排序算法。另外一方面,状态模式容许对象,在不一样的状态拥有不一样的行为。由于现实世界中的对象一般都是有状态的,因此它们在不一样状态,行为也不同。例如,VM(自动售货机)只在hasCoin状态才给你吐商品;你不投币,它是不会吐的。如今你能够清楚的看出它们的不一样之处了:它们的意图是不一样的。状态模式帮助对象管理状态,而策略模式容许Client选择不一样的行为。 java
另外一个不那么容易能看出来的区别是:是谁促使了行为的改变。策略模式中,是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对象被建立时就被提供的。ide
让咱们来看看它们之间更多的类似之处:加密
不一样之处spa
如今咱们知道,状态模式和策略模式的结构是类似的,但它们的意图不一样。让咱们重温一下它们的主要不一样之处:设计
本段译自:Difference between State and Strategy Design Pattern in Javacode
二、URL图下载地址(astah/jude):http://pan.baidu.com/s/1hqy0c88orm
三、示例
公共策略规范接口
1 package com.xinye.test.strategy; 2 /** 3 * 策略通用接口 4 * @author xinye 5 * 6 */ 7 public interface IStrategy { 8 public void strategy(); 9 }
默认策略
1 package com.xinye.test.strategy; 2 /** 3 * 默认Strategy 4 * @author xinye 5 * 6 */ 7 public class NormalStrategy implements IStrategy { 8 9 @Override 10 public void strategy() { 11 System.out.println(getClass().getSimpleName() + " strategy()"); 12 } 13 14 }
第一种策略
package com.xinye.test.strategy; /** * 第一种Strategy * @author xinye * */ public class FirstStrategy implements IStrategy { @Override public void strategy() { System.out.println(getClass().getSimpleName() + " strategy()"); } }
第二种策略
1 package com.xinye.test.strategy; 2 /** 3 * 第二种Strategy 4 * @author xinye 5 * 6 */ 7 public class SecondStrategy implements IStrategy { 8 9 @Override 10 public void strategy() { 11 System.out.println(getClass().getSimpleName() + " strategy()"); 12 } 13 14 }
策略Context
1 package com.xinye.test.strategy; 2 /** 3 * 策略模式Context 4 * @author xinye 5 * 6 */ 7 public class Context { 8 9 private IStrategy strategy = new NormalStrategy(); 10 /** 11 * 须要客户端把策略传递过来 12 * @param s 13 */ 14 public void exec(IStrategy s){ 15 strategy = s; 16 strategy.strategy(); 17 } 18 }
客户端代码
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()