设计模式之策略模式-Srategy

##使用大话设计模式案例

1. uml

设计模式之策略模式-Srategy_第1张图片

2. 代码

##Strategy策略类,定义所有支持的算法的公共接口

abstract class Strategy{
    //算法方法
    public abstract void AlgorithmInterface();
}

##具体策略类

class ConcreteStrategyA extends Strategy{
    @Override
    public void AlgorithmInterface(){
        //算法A实现方法
    }
}

class ConcreteStrategyB extends Strategy{
    @Override
    public void AlgorithmInterface(){
        //算法B实现方法
    }
}

class ConcreteStrategyC extends Strategy{
    @Override
    public void AlgorithmInterface(){
        //算法c实现方法
    }
}

##策略模式上下文

public class Context {
    //持有一个具体策略的对象
    private Strategy strategy;
    /**
     * 构造函数,传入一个具体策略对象
     * @param strategy    具体策略对象
     */
    public Context(Strategy strategy){
        this.strategy = strategy;
    }
    /**
     * 策略方法
     */
    public void ContextInterface(){
        strategy.AlgorithmInterface();
    }
}

##客户端代码

public static void main(String){
    //选择使用的策略
    Strategy s = new ConcreteStrategyA();
    Context context = new Context(s);
    context.ContextInterface();
}

3. 策略模式特点

##优点

  1. 减少了各类算法与使用算法类之间的耦合
  2. 避免了使用多重判断
  3. 扩展性良好

##缺点

  1. 策略类会增多
  2. 所有策略类暴露在客户端(可以结合简单工厂类,在context上下文中处理),将具体实现的职责由客户端转给了Context来承担,最大化减轻了客户端的职责。(但是由于还是使用了switch代码,增加一个类时,必须修改Context中的代码)
  3. public class Context {
        //持有一个具体策略的对象
        private Strategy strategy;
        /**
         * 构造函数,传入一个具体策略对象
         * @param strategy    具体策略对象
         */
        public Context(Strategy type){
            switch(type){
                case "算法A":
                    strategy = new ConcreteStrategyA();
                    break;
                   ...
            }
        }
        /**
         * 策略方法
         */
        public void ContextInterface(){
            strategy.AlgorithmInterface();
        }
    }

     

4. 使用案例

引用https://www.cnblogs.com/zhangshitong/p/6007607.html的案例,相对容易理解。

容错恢复机制
        容错恢复机制是应用程序开发中非常常见的功能。那么什么是容错恢复呢?简单点说就是:程序运行的时候,正常情况下应该按照某种方式来做,如果按照某种方式来做发生错误的话,系统并不会崩溃,也不会就此不能继续向下运行了,而是有容忍出错的能力,不但能容忍程序运行出现错误,还提供出现错误后的备用方案,也就是恢复机制,来代替正常执行的功能,使程序继续向下运行。
        举个实际点的例子吧,比如在一个系统中,所有对系统的操作都要有日志记录,而且这个日志还需要有管理界面,这种情况下通常会把日志记录在数据库里面,方便后续的管理,但是在记录日志到数据库的时候,可能会发生错误,比如暂时连不上数据库了,那就先记录在文件里面,然后在合适的时候把文件中的记录再转录到数据库中。
        对于这样的功能的设计,就可以采用策略模式,把日志记录到数据库和日志记录到文件当作两种记录日志的策略,然后在运行期间根据需要进行动态的切换。
        在这个例子的实现中,要示范由上下文来选择具体的策略算法,前面的例子都是由客户端选择好具体的算法,然后设置到上下文中。
        下面还是通过代码来示例一下。
(1)先定义日志策略接口,很简单,就是一个记录日志的方法,示例代码如下:

/**

 * 日志记录策略的接口

 */

public interface LogStrategy {

    /**

     * 记录日志

     * @param msg 需记录的日志信息

     */

    public void log(String msg);

}
 


(2)实现日志策略接口,先实现默认的数据库实现,假设如果日志的长度超过长度就出错,制造错误的是一个最常见的运行期错误,示例代码如下:

/**

 * 把日志记录到数据库

 */

public class DbLog implements LogStrategy{

    public void log(String msg) {     

       //制造错误

       if(msg!=null && msg.trim().length()>5){

           int a = 5/0;

       }

       System.out.println("现在把 '"+msg+"' 记录到数据库中");

    }

}
 

接下来实现记录日志到文件中去,示例代码如下:

/**

 * 把日志记录到文件

 */

public class FileLog implements LogStrategy{

    public void log(String msg) {

       System.out.println("现在把 '"+msg+"' 记录到文件中");

    }

}
 

(3)接下来定义使用这些策略的上下文,注意这次是在上下文里面实现具体策略算法的选择,所以不需要客户端来指定具体的策略算法了,示例代码如下:

 设计模式之策略模式-Srategy_第2张图片

(4)看看现在的客户端,没有了选择具体实现策略算法的工作,变得非常简单,故意多调用一次,可以看出不同的效果,示例代码如下:

 设计模式之策略模式-Srategy_第3张图片

 (5)小结一下,通过上面的示例,会看到策略模式的一种简单应用,也顺便了解一下基本的容错恢复机制的设计和实现。在实际的应用中,需要设计容错恢复的系统一般要求都比较高,应用也会比较复杂,但是基本的思路是差不多的。

设计模式之策略模式-Srategy_第4张图片

 作者演示了策略的一种变体。

这个例子同时说明了设计中的另外一个重要的概念,单一职责原理。

单一职责原则(SRP),就一个类而言应该仅有一个引起它变化的原因。

如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力,这种耦合会导致脆弱的设计

当变化发生时,设计会遭受到意想不到的破坏。

你可能感兴趣的:(23种设计模式,策略模式,Strategy,设计模式)