• 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; 
        }
    }
  • 相关阅读:
    Android之帧动画2
    CSS之图片关闭
    JAVA之While语句、Do和For语句
    oracle 无效字符
    java 时间制
    mybatis jdbcType date没有时分秒
    log4j说明
    spy 日志说明
    linux更新系统时间
    linux常用命令2
  • 原文地址:https://www.cnblogs.com/wanxi/p/6476228.html
Copyright © 2020-2023  润新知