美文网首页
第5章 -行为型模式-解释器模式(终)

第5章 -行为型模式-解释器模式(终)

作者: 一介书生独醉江湖 | 来源:发表于2022-07-19 10:46 被阅读0次
行为型模式(Behavioral Pattern)是对不同的对象之间划分责任和算法的抽象化;
行为型模式共有11种:
■ 模板方法模式
■ 命令模式
■ 责任链模式
■ 策略模式
■ 迭代器模式
■ 中介者模式
■ 观察者模式
■ 备忘录模式
■ 访问者模式
■ 状态模式
■ 解释器模式
一、解释器模式的简介
■ 给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子;
image.png
解释器5个角色:
  ■ 抽象表达式(Abstract Expression)角色:
    该角色声明一个所有的具体表达式角色都需要实现的抽象接口,该接口主要是一个解释操作interpret()方法;
  ■ 终结符表达式(Terminal Expression)角色:
    该角色实现了抽象表达式角色所要求的接口,文法中的每一个终结符都有一个具体终结表达式与之对应;
  ■ 非终结符表达式(Nonterminal Expression)角色:
    该角色是一个具体角色,文法中的每一条规则都对应一个非终结符表达式类;
  ■ 环境(Context)角色:
    该角色提供解释器之外的一些全局信息;
  ■ 客户端(Client)角色:
    该角色创建一个抽象语法树,调用解释操作;
二、解释器模式的优缺点
解释器模式的优点:
  ■ 简单的语法分析工具;
  ■ 扩展性,修改语法规则只要修改相应的非终结符表达式即可;
    若扩展语法,则只要增加非终结符类即可;
解释器模式的缺点:
  ■ 解释器模式会引起类膨胀;
    每个语法都要产生一个非终结符表达式,语法比较复杂时就可能产生大量的类文件,不易维护;
  ■ 采用递归调用方法;
    每个非终结符表达式只关心与自己有关的表达式,每个表达式需要知道最终的结果,必须一层一层地剥茧,无论是面向过程的语言还是面向对象的语言,递归都是在必要条件下使用的,不易调试且影响效率;
解释器模式的使用场景:
■ 重复发生的问题可以使用解释器模式;
  例如,多个应用服务器,每天产生大量的日志,需要对日志文件进行分析处理,由于各个服务器的日志格式不同,但是数据要素是相同的,按照解释器的说法就是终结符表达式都是相同的,非终结符表达式就需要制定;
■ 一个简单语法需要解释的场景;
三、解释器模式的实例
# 使用解释器模式完成四则算术运算表达式的计算;
image.png
/**
 * 算术表达式,对应解释器模式中的抽象解释器角色
 */
public interface ArithmeticExpression {

    int interpret(Variables variables);
}
/**
 * 算术表达式中的变量,对应解释器模式中的终结符表达式
 */
public class Variable implements ArithmeticExpression{
    @Override
    public int interpret(Variables variables) {
        return variables.get(this);
    }
}
import java.util.HashMap;
import java.util.Map;

/**
 * 使用Map存储各个变量的值,对应解释器模式中的环境角色
 */
public class Variables {

    Map<Variable , Integer> v = new HashMap<>();

    public void put(Variable variable , int value){
        v.put(variable , value);
    }

    public int get(Variable variable){
        return v.get(variable);
    }
}
/**
 * 加法运算 对应解释器模式中的非终结符表达式
 */
public class Plus implements ArithmeticExpression{

    private ArithmeticExpression left;

    private ArithmeticExpression right;

    public Plus(ArithmeticExpression left, ArithmeticExpression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Variables variables) {
        return left.interpret(variables) + right.interpret(variables);
    }
}
/**
 * 减法运算 对应解释器模式中的非终结符表达式
 */
public class Substract implements ArithmeticExpression{

    private ArithmeticExpression left;

    private ArithmeticExpression right;

    public Substract(ArithmeticExpression left, ArithmeticExpression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Variables variables) {
        return left.interpret(variables) - right.interpret(variables);
    }
}
/**
 * 乘法运算 对应解释器模式中的非终结符表达式
 */
public class Multiply implements ArithmeticExpression{
    private ArithmeticExpression left;

    private ArithmeticExpression right;

    public Multiply(ArithmeticExpression left, ArithmeticExpression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Variables variables) {
        return left.interpret(variables) * right.interpret(variables);
    }
}
/**
 * 除法运算 对应解释器模式中的非终结符表达式
 */
public class Division implements ArithmeticExpression{
    private ArithmeticExpression left;

    private ArithmeticExpression right;

    public Division(ArithmeticExpression left, ArithmeticExpression right) {
        this.left = left;
        this.right = right;
    }

    @Override
    public int interpret(Variables variables) {
        return left.interpret(variables) / right.interpret(variables);
    }
}
/**
 * 客户端应用类
 */
public class ClientDemo {

    public static void main(String[] args){
        Variables v = new Variables();

        Variable x = new Variable();
        Variable y = new Variable();
        Variable z = new Variable();

        v.put(x , 10);
        v.put(y , 20);
        v.put(z , 30);

        /**
         * 计算 x * (y + z / x) - x
         */
        ArithmeticExpression ae = new Substract(new Multiply(x , new Plus(y , new Division(z , x))) , x);

        System.out.println(ae.interpret(v));
    }
}
# 控制台输出:
220
参考:
摘录 《设计模式(Java版)》韩敬海主编;(微信读书APP中有资源,可以直接阅读)

相关文章

网友评论

      本文标题:第5章 -行为型模式-解释器模式(终)

      本文链接:https://www.haomeiwen.com/subject/alujirtx.html