Strategy策略设计模式

一、策略模式和状态模式的区别和联系(本部分转载自: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

让咱们来看看它们之间更多的类似之处:加密

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

不一样之处spa

如今咱们知道,状态模式和策略模式的结构是类似的,但它们的意图不一样。让咱们重温一下它们的主要不一样之处:设计

  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 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()

相关文章
相关标签/搜索