【设计模式详解】探秘解释器模式,掌握解释器模式的艺术及其神奇力量【C++代码实现示例】

其他模式的详解:

【设计模式】桥接模式详解,如何优雅地处理不同维度的系统变化? 有原理、示例、场景、优缺点及常见面试题和答案-CSDN博客

【设计模式详解】外观模式:简化复杂系统接口的大门,一键式接入,无忧使用 C++代码详解实现-CSDN博客 

【设计模式】功能无限,结构不变:探秘装饰器模式的神奇魔力,揭秘装饰器模式的设计精髓-CSDN博客

【设计模式】适配器模式 告别接口难题,让你的代码更兼容,让你的接口不再孤单,解锁接口兼容新境界,让你的代码变得更灵活!-CSDN博客

前言:

咱们一起来聊聊行为型设计模式的解释器模式。

一、原理及示例代码

解释器模式是一种行为型设计模式,它用于定义语言的文法,并且在运行时解释和执行语言中的表达式。该模式通常包含以下几个角色:

  1. 抽象表达式(Abstract Expression):定义了一个抽象的接口,用于解释和执行特定的语法规则。
  2. 终结符表达式(Terminal Expression):实现了抽象表达式接口,用于表示语言中的终结符(如变量、常量等)。
  3. 非终结符表达式(Non-terminal Expression):实现了抽象表达式接口,用于表示语言中的非终结符,通常由多个终结符或非终结符组成。
  4. 上下文(Context):包含解释器需要的全局信息,对解释器进行初始化和赋值。

下面是一个简单的 C++ 示例代码,演示了如何使用解释器模式来解释和执行简单的数学表达式:

#include <iostream>
#include <map>

// 抽象表达式
class Expression {
public:
    virtual int interpret(std::map<char, int>& context) = 0;
};

// 终结符表达式
class VariableExpression : public Expression {
private:
    char name;
public:
    VariableExpression(char name) : name(name) {}
    int interpret(std::map<char, int>& context) override {
        return context[name];
    }
};

// 非终结符表达式
class AddExpression : public Expression {
private:
    Expression* left;
    Expression* right;
public:
    AddExpression(Expression* left, Expression* right) : left(left), right(right) {}
    int interpret(std::map<char, int>& context) override {
        return left->interpret(context) + right->interpret(context);
    }
};

int main() {
    // 构建解释器需要的上下文
    std::map<char, int> context;
    context['a'] = 5;
    context['b'] = 7;

    // 构建表达式:a + b
    Expression* expression = new AddExpression(new VariableExpression('a'), new VariableExpression('b'));

    // 执行表达式
    int result = expression->interpret(context);
    std::cout << "Result: " << result << std::endl;

    delete expression;
    return 0;
}

在上面的示例中,我们定义了抽象表达式 Expression,终结符表达式 VariableExpression 和非终结符表达式 AddExpression。然后,我们创建了一个上下文 context,并构建了一个简单的数学表达式 a + b。最后,我们执行表达式并输出结果。

二、结构图

解释器模式的结构图如下所示:

  +---------------------+      +---------------------+
  |   AbstractExpression|      |   TerminalExpression|
  +---------------------+      +---------------------+
  |   interpret()       |      |   interpret()       |
  +---------------------+      +---------------------+
              |                        |
              |                        |
              +------------------------+
                           |
                           |
                  +------------------+
                  | NonterminalExpression|
                  +------------------+
                  |   interpret()    |
                  +------------------+

在上面的结构图中,我们可以看到以下几个重要的角色:

  1. AbstractExpression(抽象表达式):定义了一个抽象的接口,包含 interpret 方法,用于解释和执行特定的语法规则。
  2. TerminalExpression(终结符表达式):实现了抽象表达式接口,用于表示语言中的终结符,通常包含 interpret 方法来执行具体的解释。
  3. NonterminalExpression(非终结符表达式):同样实现了抽象表达式接口,用于表示语言中的非终结符,通常由多个终结符或非终结符组成,也包含 interpret 方法来执行具体的解释。

这些角色共同协作,使得解释器模式可以解释和执行特定语言的表达式。

三、使用场景

解释器模式通常在以下情况下使用:

  1. 当有一个简单的语法规则,并且需要解释和执行这个语法规则时,可以使用解释器模式。例如,数学表达式、逻辑表达式等都可以使用解释器模式来解释和执行。

  2. 当需要构建一个可以灵活扩展的语言解释器时,可以使用解释器模式。通过定义抽象表达式和具体的终结符表达式、非终结符表达式,可以轻松地扩展语言的语法规则。

下面分别给出这两种情况的C++示例代码:

场景一:数学表达式解释器

#include <iostream>
#include <map>

// 抽象表达式
class Expression {
public:
    virtual int interpret(std::map<char, int>& context) = 0;
};

// 终结符表达式
class VariableExpression : public Expression {
private:
    char name;
public:
    VariableExpression(char name) : name(name) {}
    int interpret(std::map<char, int>& context) override {
        return context[name];
    }
};

// 非终结符表达式
class AddExpression : public Expression {
private:
    Expression* left;
    Expression* right;
public:
    AddExpression(Expression* left, Expression* right) : left(left), right(right) {}
    int interpret(std::map<char, int>& context) override {
        return left->interpret(context) + right->interpret(context);
    }
};

int main() {
    // 构建解释器需要的上下文
    std::map<char, int> context;
    context['a'] = 5;
    context['b'] = 7;

    // 构建表达式:a + b
    Expression* expression = new AddExpression(new VariableExpression('a'), new VariableExpression('b'));

    // 执行表达式
    int result = expression->interpret(context);
    std::cout << "Result: " << result << std::endl;

    delete expression;
    return 0;
}

场景二:自定义语言解释器

#include <iostream>
#include <map>
#include <string>

// 抽象表达式
class Expression {
public:
    virtual int interpret(std::map<std::string, int>& context) = 0;
};

// 终结符表达式
class NumberExpression : public Expression {
private:
    int value;
public:
    NumberExpression(int value) : value(value) {}
    int interpret(std::map<std::string, int>& context) override {
        return value;
    }
};

// 非终结符表达式
class VariableExpression : public Expression {
private:
    std::string name;
public:
    VariableExpression(const std::string& name) : name(name) {}
    int interpret(std::map<std::string, int>& context) override {
        return context[name];
    }
};

int main() {
    // 构建解释器需要的上下文
    std::map<std::string, int> context;
    context["x"] = 5;
    context["y"] = 7;

    // 构建表达式:2 * x + y
    Expression* expression = new AddExpression(
        new MultiplyExpression(new NumberExpression(2), new VariableExpression("x")),
        new VariableExpression("y")
    );

    // 执行表达式
    int result = expression->interpret(context);
    std::cout << "Result: " << result << std::endl;

    delete expression;
    return 0;
}

在这两个示例中,我们分别展示了数学表达式解释器和自定义语言解释器的使用,演示了如何使用解释器模式来解释和执行特定的语法规则。

四、优缺点

解释器模式(Interpreter Pattern)的优点和缺点如下:

优点:

  1. 易于扩展:可以通过增加新的表达式类来扩展语言的语法规则,而不需要修改现有的代码。
  2. 易于实现语法解释:对于简单的语法规则,使用解释器模式可以很容易地实现语法解释和执行。
  3. 易于维护:将语法规则的解释功能封装在表达式类中,使得代码易于维护和理解。

缺点:

  1. 可能导致类膨胀:随着语法规则的复杂性增加,可能需要创建大量的表达式类,导致类的数量膨胀,使得系统变得复杂。
  2. 可能降低性能:解释器模式通常需要对语法规则进行解释和执行,可能会导致性能上的一些损失,特别是在处理复杂语法规则时。

总的来说,解释器模式适合用于处理简单的语法规则的解释和执行,但在处理复杂的语法规则时可能会导致类膨胀和性能损失。在选择是否使用解释器模式时,需要根据具体的场景和需求进行权衡。

------------------------------------------分界线-------------------------------------------

     5                                                          
                                                            
              +---+                                               
              |   |                                               
              |   | 3                       3                                                 |---|
        |      |   |                                                                           |   |
        |      |   +---+                   -----                  + ---+                       |   |
        |      | +      |       |            |   |                  +     |----|3              |   |
  +     |    2 | +      |       |          2 |   |     2            +     |    |               |   |
  +     |      | +      |       |            |   |                  +     |    |               |   |
  +     |  +---+ +      |       |        ----+   |   +---+          +     |    |               |   |
  +       |     +      |       |        |       |   |   |          +     |    |    ++++++|    |   |
  +     1 |     +      | 1     |      1 |       | 1 |   | 1        +     |    |    |     |    |   |
  +       |     +      |       |        |       |   |   |          +     |    |    |     |    |   |
  +   +---+     +      +---+   |    +---+       +---+   +---+      +     |    |    |     |    |   |
  +   |         +          |   |    |                       |      +     |    |    |     |    |   |
  + 0 |         +          | 0 |  0 |                       | 0    +     |    |    |     |    |   |
  +   |         +          |   |    |                       |      +     |    |    |     |    |   |
  +---+         +          +-------+                       +---+  +  +--- |    |+   |     |++ |   |+
                +                                                      
    0   1   2   3   4   5   6   7   8   9  10  11  12  13  14   15  16  17  18 19  20  21
 

相关推荐

  1. 设计模式艺术》笔记 - 解释模式

    2024-01-03 12:44:01       24 阅读
  2. C++ QT设计模式解释模式

    2024-01-03 12:44:01       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-01-03 12:44:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-01-03 12:44:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-01-03 12:44:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-01-03 12:44:01       20 阅读

热门阅读

  1. QT 高DPI解决方案

    2024-01-03 12:44:01       42 阅读
  2. 分布式(4)

    2024-01-03 12:44:01       33 阅读
  3. 分布式(3)

    2024-01-03 12:44:01       39 阅读
  4. 安卓作业001 - 显示学生信息

    2024-01-03 12:44:01       36 阅读
  5. 单片机相关知识点

    2024-01-03 12:44:01       38 阅读
  6. 提升开发效率,程序员都在使用的免费api

    2024-01-03 12:44:01       42 阅读
  7. 【ASP.NET Core 基础知识】--介绍

    2024-01-03 12:44:01       38 阅读
  8. 静态pod

    2024-01-03 12:44:01       40 阅读
  9. Unity游戏引擎的2D碰撞检测

    2024-01-03 12:44:01       48 阅读
  10. 欢迎来到MySQL优化之旅

    2024-01-03 12:44:01       46 阅读