• 策略模式


    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语句来选择这些行为情况下,可以使用策略模式来代替这些条件语句。
  • 相关阅读:
    使用线程加载指定目录下的所有子目录和文件名称到TreeView中
    《C++代码设计与重用》读后感
    无限分类编辑移动栏目代码
    查询数据库中所有记录总数不为0的数据表名称
    DES,RC2,Rijndael, TripleDes,RSA, MD5, SHA1通用的安全密码类
    SQL过滤掉空格和其他特殊字符函数
    @property详解:nonatomic,retain (转)
    UITextField控件处理键盘弹出时遮住输入框的问题
    iphone 定时器的使用
    苹果官方例子代码
  • 原文地址:https://www.cnblogs.com/lihaolihao/p/5733317.html
Copyright © 2020-2023  润新知