设计模式的分类
我们都知道有 23 种设计模式,这 23 种设计模式可分为如下三类:
- 创建型模式(5 种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
- 结构型模式(7 种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
- 行为型模式(11 种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

设计模式系列文章传送门
什么是解释器模式
解释器模式(Interpreter Pattern)是一种行为设计模式,解释器模式通过一个解释器对象处理一个语法规则,把复杂的功能分离开,然后选择需要被执行的功能,并把这些功能组合成为需要被解释执行的抽象语法树,再按照抽象语法树来解释执行,实现相应的功能。
解释器模式的组成部分
- 抽象表达式:也可以叫抽象解释器,声明一个抽象的解释操作方法,这个方法是一个抽象方法,由具体子类实现。
- 终止表达式:也可以叫终止符解释器,实现了抽象解释器,实现与语法规则中的终结符相关联的解释操作,在语法规则的语法分析树中,终结符表达式是叶子节点,它们不再包含其他表达式,这也是终止的意思的来源。
- 非终止表达式:也可以叫非终止符解释器,实现了抽象解释器,对语法规则中的非终结符进行解释操作,非终结符解释器通常包含其他表达式(终结符表达式或非终结符表达式),它在在语法规则的语法分析树中是非叶子节点。
- 上下文:包含解释器之外的一些全局信息,它为解释器的解释工作提供必要的支持。
解释器模式案例演示
解释器模式相对来说是比较冷门的设计模式,这里我准备使用生活中的加减法来演示解释器模式,例如:x + y 或者 x + y - z,下面我们使用代码来进行演示。
AbstractExpression(抽象表达式)
AbstractExpression 抽象表达式,定义了解释方法,具体代码如下:
public interface AbstractExpression {
///解释方法
int interpretation();
}
ConstantExpression(终止表达式)
ConstantExpression 是一个终止表达式,同时也是一个常量表达式,实现了抽象表达式接口,并实现了解释方法,具体代码如下:
public class ConstantExpression implements AbstractExpression {
private int number;
public ConstantExpression(int number) {
this.number = number;
}
@Override
public int interpretation() {
return number;
}
}
NumExpression(终止表达式)
NumExpression 也是一个终止表达式,但它可以从上下文中获取值,同样也实现了抽象表达式接口,并实现了解释方法,具体代码如下:
public class NumExpression implements AbstractExpression{
private String name;
public NumExpression(String name) {
this.name = name;
}
@Override
public int interpretation() {
return InterpretationContext.getValue(this.name);
}
}
AddExpression(非终止表达式)
AddExpression 是一个非终止表达式,它持有两个抽象表达式对象,同样也实现了抽象表达式接口,实现了解释方法,并在解释方法中实现了加法计算,具体代码如下:
public class AddExpression implements AbstractExpression {
private AbstractExpression left;
private AbstractExpression right;
public AddExpression(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
//实现加法
@Override
public int interpretation() {
return left.interpretation() + right.interpretation();
}
}
SubExpression(非终止表达式)
SubExpression 是一个非终止表达式,它持有两个抽象表达式对象,同样也实现了抽象表达式接口,实现了解释方法,并在解释方法中实现了减法计算,具体代码如下:
public class SubExpression implements AbstractExpression {
private AbstractExpression left;
private AbstractExpression right;
public SubExpression(AbstractExpression left, AbstractExpression right) {
this.left = left;
this.right = right;
}
//实现减法
@Override
public int interpretation() {
return left.interpretation() - right.interpretation();
}
}
InterpretationContext(上下文)
InterpretationContext 上下文中有一个 Map 容器,负责存储变量名和值之间的映射关系,并提供了存取值的方法,具体代码如下:
public class InterpretationContext {
private static final Map<String, Integer> INTERPRETATION_MAP = new HashMap<>();
public static int getValue(String key) {
return INTERPRETATION_MAP.get(key) == null ? 0 : INTERPRETATION_MAP.get(key);
}
public static void putValue(String key, Integer value) {
INTERPRETATION_MAP.put(key, value);
}
}
InterpretationClient(客户端)
InterpretationClient 客户端代码如下:
public class InterpretationClient {
public static void main(String[] args) {
NumExpression x = new NumExpression("x");
NumExpression y = new NumExpression("y");
InterpretationContext.putValue("x", 88);
InterpretationContext.putValue("y", 66);
//执行表达式:x+y
AddExpression addExpression = new AddExpression(x, y);
int addInterpretation = addExpression.interpretation();
System.out.println("执行表达式:x+y 的结果:" + addInterpretation);
//执行表达式:x+y-54
ConstantExpression constantExpression = new ConstantExpression(54);
SubExpression subExpression = new SubExpression(addExpression, constantExpression);
int subInterpretation = subExpression.interpretation();
System.out.println("执行表达式:x+y-54 的结果:" + subInterpretation);
}
}
执行结果如下:
执行表达式:x+y 的结果:154
执行表达式:x+y-54 的结果:100
可以看到我们使用解释器模式完成了 x + y 和 x + y - 100 的运算,结果符合预期。
解释器模式的优缺点
优点:
- 容易实现语法规则,解释器模式通过将语法规则表示为类层次结构,使得实现特定的语法规则变得相对容易,例如:x + y - 100。
- 扩展性好,解释器模式允许对语言的语法进行修改和扩展,由于语法规则是通过类来表示的,所以可以在运行时动态地改变语言的解释方式,来满足不同的需求。
- 代码维护下良好,因为每个语法规则都被封装在独立的类中,所以当需要修改某个语法规则的解释逻辑时,只需要在对应的类中进行修改,而不会影响到其他语法规则的解释。
缺点:
- 当语法规则变得复杂时,解释器模式的实现会变得非常复杂。
- 解释器模式需要定义很多类和解释方法,因此代码量比较大,实现起来比较复杂。
- 解释器模式通常采用递归的方式来解释语法规则,在处理复杂的语法或者大量的数据时,递归调用可能会导致性能下降。
解释器模式的使用场景
- 数学表达式的场景。
- 有业务规则的场景可以考虑使用解释器模式。
总结:本篇分享了解释器模式的概念和使用,并使用加减法的案例进行了代码演示,希望可以帮助到有需要了解解释器模式的朋友们。
1504

被折叠的 条评论
为什么被折叠?



