Java设计模式之行为型模式(策略模式)

策略模式(Strategy)

1、概述

①定义

《JAVA与模式》一书中是这样定义策略模式的:

策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

策略模式的策略是什么意思?有朋友可能会疑惑:在Java中,“策略”和“方法”有什么区别?首先,策略与方法含义相近,都指应对问题的办法手段。策略比方法更加宏观,更加正式,策略更加强调地位作用,可以看作是一种“升级版”的方法。在Java中,方法就是形如show()这样的,它是被包含在类或接口中的,只是类的成员(成员变量、成员方法)。在Java中,策略不在是方法那么简单。策略虽然与方法相近,但一个策略并不是一个类的成员单位,而是一个类(或接口)为单位。我们暂且可以把Java中的策略看作“策略类”(Strategy class)。

②结构

首先我们来看看策略模式的结构图:

这里写图片描述

  • Strategic为策略性接口,接口中定义了一个operateStrategy()方法,方法体内期望用于实现策略性接口的算法
  • Strategy1、Strategy2、Strategy3为三个独立的策略类,都实现Strategic接口的operateStrategy()方法

可见,在策略模式中,每一个策略的单位是类,而不是方法。算法被封装在策略类的内部。

· 解答疑惑

为何策略模式需要先定义一个抽象的策略接口?

答案:我们知道,在存在多个处于统一平台,拥有同等地位的类这一场景中,使这些类共同实现或继承同一个接口或父类,能够有效提高代码的扩展性和可维护性、健壮性。试想,假设现在有一个Context类,Context类中需要使用某种策略,若这些策略类没有实现共同的接口或继承共同的父类,当有策略类增加的需求时,我们不但要写定义新的策略类的代码,还要在Context类中依次添加策略类,这样就违背了开闭原则;若这些策略类实现了共同的接口或继承共同的父类,当Context需要使用某种策略时,就可以通过一个方法,这个方法以接口类或者父类类型的引用来充当参数,充分利用了Java中多态的特性,且若有增多策略类的需求时,仅需写定义新的策略类的代码,而无需修改Context中的代码。

3、实例分析

利用策略模式实现四个策略类,分别为:Plus、Minus、Multiple、Divide,由这四个策略类构成几个基本的计算器。每一个策略类中封装了对应的算法。

UML图:

这里写图片描述

代码:

/**
 * @author Hanlin Wang
 */

public class StrategyMode {
    public static void main(String[] args) {
        //选择不同的策略Strategy:加、减、乘、除。
        Plus plus = new Plus();
        double res = plus.calculate("1+1+2+5");
        System.out.println(res);

        Minus minus = new Minus();
        double res2 = minus.calculate("9-6-1");
        System.out.println(res2);

        Multiple multiple = new Multiple();
        double res3 = multiple.calculate("4*8*2");
        System.out.println(res3);

        Divide divide = new Divide();
        double res4 = divide.calculate("64/4/2");
        System.out.println(res4);
    }
}

//方法模板
interface Calculator{
    double calculate(String exp);
}

//实现模板
class Plus implements Calculator{
    public double calculate(String exp) {
        String[] seg = exp.split("\+");
        double res = 0.0;
        for (int i = 0; i < seg.length; i++) {
            res += Double.parseDouble(seg[i]);
        }
        return res; 
    }
}

class Minus implements Calculator{
    public double calculate(String exp) {
        String[] seg = exp.split("\-");
        double res = Double.parseDouble(seg[0]);
        for (int i = 1; i < seg.length; i++) {
            res -= Double.parseDouble(seg[i]);
        }
        return res; 
    }
}

class Multiple implements Calculator{
    public double calculate(String exp) {
        String[] seg = exp.split("\*");
        double res = 1.0;
        for (int i = 0; i < seg.length; i++) {
            res *= Double.parseDouble(seg[i]);
        }
        return res; 
    }
}

class Divide implements Calculator{
    public double calculate(String exp) {
        String[] seg = exp.split("\/");
        double res = Double.parseDouble(seg[0]);
        for (int i = 1; i < seg.length; i++) {
            res /= Double.parseDouble(seg[i]);
        }
        return res; 
    }
}
原文地址:https://www.cnblogs.com/wanxi/p/6476228.html