解释器模式

简介: 解释器模式是一种行为型设计模式,用于定义语言的文法表示并提供解释器处理语句或表达式。它将语法规则与解释逻辑分离,便于扩展和维护。适用于简单的语法规则、固定文法结构及重复使用的语法解释场景,如数学表达式求值、SQL解析和简单脚本语言。优点包括易于扩展新规则和分离语法逻辑,但复杂文法会导致类数量激增,维护困难。

解释器模式详解

概念

解释器模式(Interpreter Pattern)是一种行为型设计模式,用于定义一个语言的文法表示,并提供一个解释器来处理该语言中的语句或表达式。它可以让语法规则和解释逻辑分离,从而轻松地扩展和维护。

特点

  • 分离语法和逻辑:语言的规则由语法树表示,解释逻辑由解释器实现。
  • 递归调用:通常通过递归结构解析和计算语法树。
  • 扩展性强:新增规则只需扩展语法树节点和解释逻辑。

适用场景

  • 简单的语法规则:适用于开发简单的脚本语言、配置文件解析器等。
  • 固定文法结构:需要定义一套固定文法并对其进行解析。
  • 重复使用的语法解释:如表达式求值器、命令解析器。

使用案例

1. 数学表达式求值

  • 场景:对表达式如3 + 5 * (2 - 4)进行解析和计算。
  • 解决:用语法树表示表达式,并实现解释器计算结果。

2. SQL解析

  • 场景:实现对SQL查询语句的解析和执行。
  • 解决:构建SQL语法树并解析执行。

3. 简单脚本语言

  • 场景:如游戏中配置简单行为脚本。
  • 解决:为脚本语言定义文法规则和解释器。

优缺点

优点 缺点
易于扩展新规则,符合开闭原则 文法复杂时会导致类数量激增,难以维护
文法和解释逻辑分离,结构清晰 不适用于复杂语法,会增加系统复杂性
便于实现自定义语言和表达式解析 对效率要求高的场景不适用,性能可能较低

类图


C++实现

#include <iostream>
#include <string>
#include <memory>
#include <vector>

// 上下文类
class Context {
public:
   std::string input;
   int output = 0;
};

// 抽象表达式
class AbstractExpression {
public:
   virtual ~AbstractExpression() = default;
   virtual void Interpret(Context& context) = 0;
};

// 终结符表达式
class TerminalExpression : public AbstractExpression {
private:
   std::string match;
public:
   explicit TerminalExpression(const std::string& match) : match(match) {}
   void Interpret(Context& context) override {
       if (context.input.find(match) != std::string::npos) {
           context.output++;
       }
   }
};

// 非终结符表达式
class NonTerminalExpression : public AbstractExpression {
private:
   std::vector<std::unique_ptr<AbstractExpression>> expressions;
public:
   void Add(std::unique_ptr<AbstractExpression> expression) {
       expressions.push_back(std::move(expression));
   }

   void Interpret(Context& context) override {
       for (auto& expression : expressions) {
           expression->Interpret(context);
       }
   }
};

// 示例用法
int main() {
   Context context{"hello world"};
   NonTerminalExpression root;
   root.Add(std::make_unique<TerminalExpression>("hello"));
   root.Add(std::make_unique<TerminalExpression>("world"));

   root.Interpret(context);
   std::cout << "Matched words: " << context.output << std::endl;

   return 0;
}


C#实现

using System;
using System.Collections.Generic;

// 上下文类
public class Context {
   public string Input { get; set; }
   public int Output { get; set; } = 0;
}

// 抽象表达式
public abstract class AbstractExpression {
   public abstract void Interpret(Context context);
}

// 终结符表达式
public class TerminalExpression : AbstractExpression {
   private readonly string _match;

   public TerminalExpression(string match) {
       _match = match;
   }

   public override void Interpret(Context context) {
       if (context.Input.Contains(_match)) {
           context.Output++;
       }
   }
}

// 非终结符表达式
public class NonTerminalExpression : AbstractExpression {
   private readonly List<AbstractExpression> _expressions = new();

   public void Add(AbstractExpression expression) {
       _expressions.Add(expression);
   }

   public override void Interpret(Context context) {
       foreach (var expression in _expressions) {
           expression.Interpret(context);
       }
   }
}

// 示例用法
class Program {
   static void Main(string[] args) {
       var context = new Context { Input = "hello world" };
       var root = new NonTerminalExpression();
       root.Add(new TerminalExpression("hello"));
       root.Add(new TerminalExpression("world"));

       root.Interpret(context);
       Console.WriteLine($"Matched words: {context.Output}");
   }
}

相关文章
|
测试技术 持续交付 开发工具
《Git 简易速速上手小册》第6章:Git 在持续集成/持续部署(CI/CD)中的应用(2024 最新版)
《Git 简易速速上手小册》第6章:Git 在持续集成/持续部署(CI/CD)中的应用(2024 最新版)
312 2
|
11月前
|
XML 设计模式 JSON
模板方法模式(Template Method Pattern)
模板方法模式是一种行为型设计模式,定义一个操作中的算法骨架,将某些步骤的实现延迟到子类。子类可以在不改变算法结构的情况下重新定义算法的某些步骤。适用于多个类有相似操作流程且部分步骤需要定制的场景。优点包括高复用性、扩展性强和清晰明确;缺点是灵活性降低和可能引入性能开销。示例包括文件解析和策略模式的对比。
模板方法模式(Template Method Pattern)
|
11月前
|
存储 设计模式 算法
命令模式(Command Pattern)
命令模式是一种行为型设计模式,将请求封装为对象,实现参数化请求、支持撤销操作和记录日志。适用于需要解耦发送者和接收者的场景,如智能家居系统中的遥控器控制电灯开关并支持撤销功能。优点包括解耦、支持撤销与恢复操作,但过度使用会增加系统复杂度。
|
11月前
|
设计模式 C# C++
责任链模式(Chain of Responsibility Pattern)
责任链模式是一种行为型设计模式,允许多个对象按顺序处理请求,直到某个对象处理为止。适用于多个对象可能处理同一请求的场景,如请假审批流程。优点是灵活性高、降低耦合,但责任链过长可能影响性能。
|
11月前
|
设计模式 数据库 C#
外观模式(Facade Pattern)
外观模式(Facade Pattern)是一种结构型设计模式,为子系统中的一组接口提供一个一致的接口。它通过一个高层接口简化子系统的复杂性,使客户端更容易使用。外观模式的核心角色包括外观(Facade)和子系统(Subsystems),主要优点是降低复杂性和松耦合,适用于简化接口、分层设计和遗留代码集成等场景。
|
11月前
|
设计模式 API C#
桥接模式(Bridge Pattern)
桥接模式是一种结构型设计模式,通过将抽象部分与实现部分分离,使它们可以独立变化,从而提高系统的灵活性和扩展性。主要角色包括抽象化、扩展抽象化、实现和具体实现。适用于多变化维度的系统,如跨平台开发、图形系统等。优点是分离抽象与实现,减少子类数量;缺点是增加了复杂性和理解难度。
|
11月前
|
设计模式 算法 定位技术
策略模式(Strategy Pattern)
策略模式(Strategy Pattern)是一种行为型设计模式,允许在运行时选择算法或行为,而不是在编译时确定。通过将具体算法封装成独立的类,并通过统一接口与客户端交互,实现算法的动态替换,避免代码重复和复杂条件语句。适用于支付方式切换、导航路径选择等场景。
|
11月前
|
设计模式 Java C#
装饰模式(Decorator Pattern)
装饰模式是一种结构型设计模式,允许在不修改原有对象的情况下动态添加功能。它通过装饰类层层叠加实现功能扩展,适用于需要在运行时动态添加、修改或移除对象行为的场景。装饰模式的核心角色包括抽象组件、具体组件、抽象装饰和具体装饰。该模式的优点在于动态扩展功能、避免类爆炸和遵守开放-封闭原则,但可能会导致对象数量增加和调试困难。常见使用场景包括图形系统中的动态效果和输入流的功能扩展。
|
11月前
|
设计模式 安全 C#
单例模式详解
单例模式是一种常用的创建型设计模式,确保某个类只有一个实例,并提供一个全局访问点。本文详细介绍了单例模式的定义、特点、适用场景、优缺点及实现代码(C++ 和 C#),并探讨了线程安全的实现细节和与依赖注入的结合使用。
|
11月前
|
设计模式 IDE 数据可视化
UML中类图的介绍与使用
类图是 UML 中用于展示系统静态结构的重要工具,包括类、接口及其关系。类图有助于系统可视化、团队沟通、发现设计问题、文档化系统和辅助开发工具。类图的三大元素是类、接口和关系,其中关系又细分为关联、聚合、组合、继承、实现和依赖。类图在设计模式学习和实际开发中非常重要,许多现代 IDE 都支持从类图生成代码或从代码生成类图。