策略模式

1,策略模式的定义

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

2,结构图和说明

       

 
    • Strategy:策略接口,用来约束一系列具体的策略算法。Context使用这个忌口来调用具体的策略实现定义的算法。

    • ConcreteStrategy:具体的策略实现,也就是具体的算法实现。

             Context:上下文,负责和具体的策略类交互。通常上下文会持有一个真正的策略实现,上下文海可以让具体的策略类获取上下文的数据,甚至让具体的策略类来回调上下文的方法。

 1 /**
 2  * 
 3  *策略定义算法的接口
 4  *
 5  */
 6 public interface Strategy {
 7     /**
 8      * 算法的某个接口,可以传入参数,也可以有返回值
 9      */
10     public abstract void algorithmInterface();
11 
12 }
 1 /**
 2  * 实现具体的算法
 3  */
 4 public class ConcreteStrategyA implements Strategy {
 5 
 6     @Override
 7     public void algorithmInterface() {
 8         // TODO 
 9         
10     }
11 
12 }
1 public class ConcreteStrategyB implements Strategy{
2 
3     @Override
4     public void algorithmInterface() {
5         // TODO 
6         
7     }
8 
9 }
1 public class ConcreteStrategyC implements Strategy{
2 
3     @Override
4     public void algorithmInterface() {
5         // TODO 
6         
7     }
8 
9 }
 1 public class Context {
 2     private Strategy mStrategy;
 3     
 4     public Context(Strategy strategy) {
 5         this.mStrategy = strategy;
 6     }
 7     
 8     public void contextInterface() {
 9         mStrategy.algorithmInterface();
10     }
11 
12 }

3,策略模式的功能

     策略模式的功能是把具体的算法实现从具体的业务处理中独立出来,把他们实现成为单独的算法类,从而形成一些列的算法,并让这些算法可以相互替换。
     提示:策略模式的重心不是如何实现算法,而是如何组织,调用这些算法,从而让程序结构更灵活,具有更好的维护性和扩展性。 

4.算法的平等性
  • 策略模式是一个很大的特点就是各个策略模式的平等性。对于一系列具体的策略算法,大家的地位是完全一样的,正式因为这个平等性,才能实现算法之间可以相互替换

  • 所有的策略算法的实现上也是相互独立的,相互之间是没有依赖的。

  • 策略算法是相同行为的不同实现

5.Strategy 的实现方式
     Strategy常见的实现方式是接口,但是如果多个算法具有公共功能的话,可以把Stratege实现成为抽象类,然后把多个算法 的公共功能实现到Strategy中。
 
6.Strategy 的实现方式
  1. 先是客户端来选择并创建具体的策略对象。
  2. 然后客户端创建上下文。
  3. 接下来客户端就可以调用上线文的方法来执行功能了,在调用的时候,从客户端传入算法需要的参数
  4. 上下文接到客户的调用请求,会把这个请求转发给他持有的Strategy。
   顺序图
  
 
7,容错恢复机制
     程序运行的时候,正常情况下应该按照某种方式来做,如果按照某种方式来做发生错误的话,系统不会崩溃,也不会就此不能继续向下运行了,而是有容忍出错的能力,不但能容忍程序运行出现错误,还提供出现错误后的被用方案,也就是恢复机制,来代替正常执行的功能,是程序继续向下运行。 
    
 1 /**
 2  * 日志记录策略的接口
 3  */
 4 public interface LogStrategy {
 5     
 6     public void log(String msg);
 7 }
 8 
 9 
10 /**
11  * 把日志记录到数据中
12  */
13 public class DbLog implements LogStrategy {
14 
15     @Override
16     public void log(String msg) {
17         if (msg != null && msg.trim().length() > 5) {
18             int a = 5/0;
19         }
20         System.out.println("现在把' "+msg+"' 记录到数据库中");
21     }
22 
23 }
24 
25 /**
26  * 把日志记录到文件中
27  */
28 public class FileLog implements LogStrategy{
29 
30     @Override
31     public void log(String msg) {
32         System.out.println("现在把' "+msg+"' 记录到文件中");
33         
34     }
35 
36 }
37 
38 public class Client {
39 
40     public static void main(String[] args) {
41         LogContext log = new LogContext();
42         log.log("记录日志");
43         log.log("再次记录日志");
44     }
45 
46 }
47 
48 
49 输出:
50 现在把' 记录日志' 记录到数据库中
51 现在把' 再次记录日志' 记录到文件中

8,策略模式的优缺点

优点
  1,定义一系列算法
    策略模式的功能就是定义一系列算法,实现让这些算法可以相互替换。

  2,避免多重条件语句

  3,更好的扩展性
    在策略模式中扩展新的策略实现非常容易,只要增加新的策略实现类,然后在使用策略的地方选择使用这个新的策略实现就可以了。

缺点
  1,客户必须了解每种策略的不同
      策略模式也有缺点,比如让客户端来选择具体使用哪一个策略,这就需要客户了解所有的策略,还要了解各种策略的功能和不同,这样才能做出正确               的选择,而且这样也暴露了策略的具体实现。

  2,增加了对象数目

  3,只适合扁平的算法结构

  
9,策略模式的本质
 
      策略模式的本质:分离算法,选择实现


10,何时选用策略模式
  • 出现有许多相关的类,仅仅是行为有差别的情况下,可以使用策略模式来使用多个行为中的一个配置一个类的方法,实现算法动态切换
  • 出现同一个算法,有很多不同实现的情况下,可以使用策略模式来把这些“不同的实现”实现成为一个算法的类层次。
  • 需要封装算法中,有与算法相关数据的情况下,可以使用策略模式来避免暴露这些跟算法相关的数据结构
  • 出现抽象一个定义了很多行为的类,并且通过多个if-else语句来选择这些行为情况下,可以使用策略模式来代替这些条件语句。
原文地址:https://www.cnblogs.com/lihaolihao/p/5733317.html