JavaScript 解释器模式 | 七日打卡

1,439 阅读2分钟

解释器模式

解释器模式(Interpreter Pattern), 提供了评估语言的语法或表达式的方式,它属于行为模式。

这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式常被用在 babel、sass、less 解析、符号处理引擎等。

意图

给定一个语言,定义它的文法表示,并定义一个解释器,这个解释器使用该标识来解释语言中的句子。

比如说,我们开发中经常会用到的正则表达式,它就是解释器模式的一种应用,解释器会根据正则表达式的固定文法,去对一个正则表达式进行解释。

场景

如果一种特定类型的问题,发生的频率足够的高,那么它就可能值得将该问题的个个实例表述为一个简单语言中的句子。这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题

  1. 可以将一个需要解释执行的语言中的句子,表示为一个抽象语法树;
  2. 一些重复出现的问题可以用一种简单的语言来进行表达;
  3. 一个简单语法需要解释的场景

优点

  1. 可扩展性比较好
  2. 灵活性高
  3. 易于实现简单的文法

缺点

  1. 可利用的场景比较少
  2. 对于复杂文法的解析器维护困难
  3. 解释器模式会引起类的膨胀
  4. 解释器模式大量采用了递归和循环的调用方法,执行效率低下,性能消耗比较高

示例代码

我们定义了一个作为上下文中主要解释器的 TerminalExpression 类。
其他的类 OrExpression、AndExpression 用于创建组合式表达式。

// 终端解释器
class TerminalExpression {
    constructor(data) {
        this.data = data
    }

    interpret(context) {
        if(context.includes(context)){
            return true
        }

        return false
    }
}

// 或 的组合表达式
class OrExpression {
    constructor(expr1, expr2) {
        this.expr1 = expr1
        this.expr2 = expr2
    }

    interpret(context) {
        return this.expr1.interpret(context) || this.expr2.interpret(context)
    }
}

// 与 的组合表达式
class AndExpression {
    constructor(expr1, expr2) {
        this.expr1 = expr1
        this.expr2 = expr2
    }

    interpret(context) {
        return this.expr1.interpret(context) && this.expr2.interpret(context)
    }
}

const robert = new TerminalExpression('Robert')
const john = new TerminalExpression('John')
const isMale = new OrExpression(robert, john)

const julie = new TerminalExpression('Julie')
const married = new TerminalExpression('Married ')
const isMarriedWoman = new AndExpression(julie, married)

console.log(`John is male ? ${isMale.interpret('john')}`) // John is male ? true
console.log(`Julie is a married women ? ${isMarriedWoman.interpret('Married Julie')}`) // Julie is a married women ? true