【设计模式-行为型】解释器模式

一、什么是解释器模式

到此为止23种解释器都将介绍完毕,下面说最后一个设计模式解释器模式。有许多谍战剧大家都会看过,在谍战剧中经常会有一些主要情节需要进行加密传递。间谍会接受或者发送加密信息。比如用收音机接收指令或者消息。间谍会根据特定的解码书去解码收音机传递过来的指令。同样的情节,在电视剧《潜伏》中也经常会出现。解释器模式为自定义语言的设计和实现提供了一种解决方案,它用于定义一组文法规则并通过这组文法规则来解释语言中的句子。虽然解释器模式的使用频率不是特别高,但是它在正则表达式、XML文档解释等领域还是得到了广泛使用。

二、为什么使用解释器模式

在电视剧《潜伏》中,地下党员通过特定的编码和通信方式进行情报传递,这种机制很好地体现了解释器模式的核心思想。通过解释器模式,我们可以模拟剧中情报的传递和解析过程,使得代码更加清晰和易于维护。

  • 需要灵活扩展的语言:地下党员们将密码语言的情报内容分解为基本元素并解释。在《潜伏》中,地下党员们经常需要传递秘密情报。这些情报往往以一种特殊的"密码语言"来表达,比如通过书信、暗号等方式。假设地下党员们使用一种简单的密码语言来传递信息,例如:"红色的花" 表示 "紧急行动"。"蓝色的信" 表示 "安全撤离"。"黄色的信封" 表示 "等待进一步指示"。这些密码语言可以看作是一种简单的"语言",而情报的内容(如"红色的花")可以看作是这种语言的"句子"。为了能够正确解释这些句子,地下党员们需要将其分解为更基本的元素(如"颜色"和"物品"),并根据预定义的规则进行解释。

  • 解析和执行简单语言:密码语言的规则简单,便于解释。在《潜伏》中,地下党员们使用的密码语言相对简单,只有几种颜色和物品的组合。这种简单的语言使得情报的传递和解释更加容易,同时也降低了被敌人破解的风险。

  • 用简单的语言来表达重复出现的问题:地下党员们用简单的密码语言来传递重复出现的情报。在《潜伏》中,地下党员们经常需要传递一些重复出现的情报内容,如"紧急行动""安全撤离"等。为了方便传递和解释,他们设计了一种简单的密码语言,或者手势来表示这些重复出现的问题。

  • 对执行效率要求不高:情报传递的频率和量都不大,不需要快速执行。在《潜伏》中,地下党员们传递情报的频率相对较低,且每次传递的情报量也不大。因此,他们可以花费一些时间来解释密码语言,而不需要追求极高的执行效率。

三、解释器模式示例

1、定义抽象表达式接口(Abstract Expression)

java 复制代码
public interface Expression {
    String interpret(Context context);
}

2. 定义上下文类(Context)

java 复制代码
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方法来解析整个表达式。

java 复制代码
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、场景

java 复制代码
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);
    }
}

//输出
解析结果: 行动,停止,撤退
相关推荐
杨充20 小时前
10.可测试性实战设计
设计模式·开源·代码规范
杨充20 小时前
9.重构十二式的实战
设计模式·开源·代码规范
杨充20 小时前
6.设计原则的全景图
设计模式·开源·全栈
杨充20 小时前
2.面向对象的特性
设计模式
杨充20 小时前
7.SOLID原则案例汇
设计模式·开源·全栈
杨充20 小时前
8.反模式与坏味道
设计模式·开源·代码规范
杨充20 小时前
3.接口vs抽象类比较
设计模式
咖啡八杯1 天前
文法、BNF与AST
java·设计模式·解释器模式·ast·文法
咖啡八杯1 天前
GoF设计模式——解释器模式
java·后端·spring·设计模式