【设计模式-行为型】解释器模式
一、什么是解释器模式
到此为止23种解释器都将介绍完毕,下面说最后一个设计模式解释器模式。有许多谍战剧大家都会看过,在谍战剧中经常会有一些主要情节需要进行加密传递。间谍会接受或者发送加密信息。比如用收音机接收指令或者消息。间谍会根据特定的解码书去解码收音机传递过来的指令。同样的情节,在电视剧《潜伏》中也经常会出现。解释器模式为自定义语言的设计和实现提供了一种解决方案,它用于定义一组文法规则并通过这组文法规则来解释语言中的句子。虽然解释器模式的使用频率不是特别高,但是它在正则表达式、XML文档解释等领域还是得到了广泛使用。
二、为什么使用解释器模式
在电视剧《潜伏》中,地下党员通过特定的编码和通信方式进行情报传递,这种机制很好地体现了解释器模式的核心思想。通过解释器模式,我们可以模拟剧中情报的传递和解析过程,使得代码更加清晰和易于维护。
-
需要灵活扩展的语言:地下党员们将密码语言的情报内容分解为基本元素并解释。在《潜伏》中,地下党员们经常需要传递秘密情报。这些情报往往以一种特殊的“密码语言”来表达,比如通过书信、暗号等方式。假设地下党员们使用一种简单的密码语言来传递信息,例如:“红色的花” 表示 “紧急行动”。“蓝色的信” 表示 “安全撤离”。“黄色的信封” 表示 “等待进一步指示”。这些密码语言可以看作是一种简单的“语言”,而情报的内容(如“红色的花”)可以看作是这种语言的“句子”。为了能够正确解释这些句子,地下党员们需要将其分解为更基本的元素(如“颜色”和“物品”),并根据预定义的规则进行解释。
-
解析和执行简单语言:密码语言的规则简单,便于解释。在《潜伏》中,地下党员们使用的密码语言相对简单,只有几种颜色和物品的组合。这种简单的语言使得情报的传递和解释更加容易,同时也降低了被敌人破解的风险。
-
用简单的语言来表达重复出现的问题:地下党员们用简单的密码语言来传递重复出现的情报。在《潜伏》中,地下党员们经常需要传递一些重复出现的情报内容,如“紧急行动”“安全撤离”等。为了方便传递和解释,他们设计了一种简单的密码语言,或者手势来表示这些重复出现的问题。
-
对执行效率要求不高:情报传递的频率和量都不大,不需要快速执行。在《潜伏》中,地下党员们传递情报的频率相对较低,且每次传递的情报量也不大。因此,他们可以花费一些时间来解释密码语言,而不需要追求极高的执行效率。
三、解释器模式示例
1、定义抽象表达式接口(Abstract Expression)
public interface Expression {
String interpret(Context context);
}
2. 定义上下文类(Context)
public class Context {
private Map<String, String> variables = new HashMap<>();
public void setVariable(String key, String value) {
variables.put(key, value);
}
public String getVariable(String key) {
return variables.getOrDefault(key, "");
}
}
3. 实现具体表达式类(Concrete Expression)
终结符表达式(Terminal Expressions)是解析过程中的基本单元,直接返回它们的值,不需要进一步解析。
非终结符表达式(Non-Terminal Expressions)是由多个终结符表达式或非终结符表达式组合而成的复杂表达式,通过递归调用其他表达式的interpret
方法来解析整个表达式。
public class CodeExpression implements Expression {
private String code;
public CodeExpression(String code) {
this.code = code;
}
@Override
public String interpret(Context context) {
return context.getVariable(code);
}
}
public class MessageExpression implements Expression {
private String message;
public MessageExpression(String message) {
this.message = message;
}
@Override
public String interpret(Context context) {
return message;
}
}
public class CompositeExpression implements Expression {
private List<Expression> expressions = new ArrayList<>();
public void add(Expression expression) {
expressions.add(expression);
}
@Override
public String interpret(Context context) {
StringBuilder result = new StringBuilder();
for (Expression expression : expressions) {
result.append(expression.interpret(context));
}
return result.toString();
}
}
4、场景
public class Main {
public static void main(String[] args) {
// 创建上下文
Context context = new Context();
context.setVariable("A", "行动");
context.setVariable("B", "停止");
context.setVariable("C", "撤退");
// 构建表达式
CompositeExpression compositeExpression = new CompositeExpression();
compositeExpression.add(new CodeExpression("A"));
compositeExpression.add(new MessageExpression(","));
compositeExpression.add(new CodeExpression("B"));
compositeExpression.add(new MessageExpression(","));
compositeExpression.add(new CodeExpression("C"));
// 解释表达式
String result = compositeExpression.interpret(context);
System.out.println("解析结果: " + result);
}
}
//输出
解析结果: 行动,停止,撤退