0%

设计模式之行为型模式(三):解释器模式

1. 解释器模式概述

  • 概念

    • 给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中的句子
    • 例如:使用中文编写出十以内的加减法公式。从表达式计算出整数的过程,称之为解释(interpret)
  • 特点

    • 在解释器模式中,不可拆分的最小单元称之为终结表达式;可以被拆分的表达式称之为非终结表达式
    • 解释器具有一定的拓展性,当需要添加其他计算符时,可以通过添加 Operator 的子类来完成。但添加后需要按照运算优先级修改计算规则。所以,一个完整的解释器模式是非常复杂的,实际开发中几乎没有需要自定义解释器的情况
  • 应用

    • 正则表达式匹配字符串,用到的正则表达式就是一个解释器
  • Demo

    • 数字和计算符公共的接口

      1
      2
      3
      interface Expression {
      int interpret();
      }
    • 解释数字类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      public class Number implements Expression {
      int number;

      public Number(char word) {
      switch (word) {
      case '零':
      number = 0;
      break;
      case '一':
      number = 1;
      break;
      case '二':
      number = 2;
      break;
      case '三':
      number = 3;
      break;
      case '四':
      number = 4;
      break;
      case '五':
      number = 5;
      break;
      case '六':
      number = 6;
      break;
      case '七':
      number = 7;
      break;
      case '八':
      number = 8;
      break;
      case '九':
      number = 9;
      break;
      default:
      break;
      }
      }

      @Override
      public int interpret() {
      return number;
      }
      }
    • 将计算符提取出共同的抽象父类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      abstract class Operator implements Expression {
      Expression left;
      Expression right;

      Operator(Expression left, Expression right) {
      this.left = left;
      this.right = right;
      }
      }
    • 加法类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      class Add extends Operator {

      Add(Expression left, Expression right) {
      super(left, right);
      }

      @Override
      public int interpret() {
      return left.interpret() + right.interpret();
      }
      }
    • 减法类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      class Sub extends Operator {

      Sub(Expression left, Expression right) {
      super(left, right);
      }

      @Override
      public int interpret() {
      return left.interpret() - right.interpret();
      }
      }
    • 计算类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      class Calculator {
      int calculate(String expression) {
      Stack<Expression> stack = new Stack<>();
      for (int i = 0; i < expression.length(); i++) {
      char word = expression.charAt(i);
      switch (word) {
      case '加':
      stack.push(new Add(stack.pop(), new Number(expression.charAt(++i))));
      break;
      case '减':
      stack.push(new Sub(stack.pop(), new Number(expression.charAt(++i))));
      break;
      default:
      stack.push(new Number(word));
      break;
      }
      }
      return stack.pop().interpret();
      }
      }
    • 测试类

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      public class Client {
      @Test
      public void test() {
      Calculator calculator = new Calculator();
      String expression1 = "一加一";
      String expression2 = "一加一加一";
      String expression3 = "二加五减三";
      String expression4 = "七减五加四减一";
      String expression5 = "九减五加三减一";
      // 输出: 一加一 等于 2
      System.out.println(expression1 + " 等于 " + calculator.calculate(expression1));
      // 输出: 一加一加一 等于 3
      System.out.println(expression2 + " 等于 " + calculator.calculate(expression2));
      // 输出: 二加五减三 等于 4
      System.out.println(expression3 + " 等于 " + calculator.calculate(expression3));
      // 输出: 七减五加四减一 等于 5
      System.out.println(expression4 + " 等于 " + calculator.calculate(expression4));
      // 输出: 九减五加三减一 等于 6
      System.out.println(expression5 + " 等于 " + calculator.calculate(expression5));
      }
      }
-------------------- 本文结束感谢您的阅读 --------------------