文章目录

  • 解析器模式(Interpreter)
    • 定义
    • 动机
    • 结构图
    • 代码
    • 要点
    • 总结

在特定领域中,某些变化虽然频繁,但可以抽象为某种规则。这时候,结合特定领域,将问题抽象为语法规则,从而给出在该领域下的一般性解决方案。

典型模式:Interpreter。

解析器模式(Interpreter)

定义

给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。

——《设计模式》GoF

动机

  • 在软件构建过程中,如果某一特定领域的问题比较复杂,类似的结构不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。
  • 在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子,从而达到解决问题的目的。

结构图

代码

#include <iostream>
#include <map>
#include <stack>using namespace std;
class Expression {
public:virtual int interpreter(map<char, int> var) = 0;virtual ~Expression(){}
};
//变量表达式(解析变量值)
class VarExpression: public Expression {char key;
public:VarExpression(const char& key){this->key = key;}int interpreter(map<char, int> var) override {return var[key];}
};
//符号表达式
class SymbolExpression : public Expression {
protected://运算符左右两个参数Expression* left;Expression* right;
public:SymbolExpression( Expression* left, Expression* right):left(left),right(right){}
};
//加法运算
class AddExpressin : public SymbolExpression {
public:AddExpression(Expression* left, Expression* right):SymbolExpression(left,right){}int interpreter(map<char, int> var) override{return left->interpreter(var) + right->interpreter(var);}
};
//减法运算
class SubExpression : public SymbotExpression {
public:SubExpression(Expression* left, Expression* right):SymbolExpression(left,right){}int interpreter(map<char, int> var) override{return left->interpreter(var) - right->interpreter(var);}
}
//解析规则
Expression* analyse(string expstr) {stack<Expression*> expStack;Expression* left = nullptr;Expression* right = nullptr;for(int i=0; i<expStr.size(); i++){switch(expStr[i]){case '+'://加法运算Left = expStack.top();right = new VarExpression(expStr[++i]);expstack.push(new AddExpression(left, right));break;case '-'://减法运算left = expStack.top();right = new VarExpression(expStr[++i]);expstack.push(new SubExpression(left, right));break;default://变量表达式expStack.push(new VarException(expStr[i]));}Exception* exception = expStack.top();return exception;}
}
void release(Expression* expression){//释放表达式树的节点内存。
}int main(int argc, const char * argv[]) {string expStr = "a+b-c+d-e+f";map<char, int> var;var.insert(make_pair('a',5));var.insert(make_pair('b',2));var.insert(make_pair('c',1));var.insert(make_pair('d',6));Expression* expression = analyse(expStr);int result = expression->interpreter(var);cout<<result<<endl;release(expression);return 0;
}

上面表达式可解析为下面的树形结构:

要点

  • Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”才适合使用Interpreter模式。
  • 使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。
  • Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interperter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。

总结

面向对象的Interpreter模式适合简单的规则表示,对于复杂的文法表示会造成非常庞大的层次结构,产生非常多的虚函数指针,造成性能问题。相对来说,在今天,这种模式应用场景还是比较少了。

李建忠设计模式之”领域规则“模式相关推荐

  1. 李建忠设计模式之“单一职责”模式

    文章目录 装饰器模式(Decorator) 定义 动机 结构图 代码 要点 总结 桥方法模式(Bridge) 定义 动机 结构图 代码 要点 总结 在软件组件的设计中,如果责任划分的不清晰,使用继承得 ...

  2. 李建忠设计模式之“组件协作”模式

    文章目录 模板方法模式(Template Method) 定义 动机 结构图 代码 要点 总结 策略模式(Strategy) 定义 动机 结构图 代码 要点 总结 观察者模式(Observer/Eve ...

  3. 李建忠设计模式之“对象创建”模式

    文章目录 工厂方法模式(Factory Method) 定义 动机 结构图 代码 要点 总结 抽象工厂模式(Abstract Factory) 定义 动机 结构图 代码 要点 总结 原型模式(Prot ...

  4. 李建忠设计模式之”行为变化“模式

    文章目录 命令模式(Command) 定义 动机 结构图 代码 要点 总结 访问器模式(visitor) 定义 动机 结构图 代码 要点 总结 在组件的构建过程中,组件行为的变化经常导致组件本身剧烈的 ...

  5. 李建忠设计模式——策略模式Strategy

    目录 1.策略模式定义 1.动机 2.模式定义 3.结构 2.实现例子 1.问题描述 2.代码实现 3.要点总结 4.参考 1.策略模式定义 1.动机 软件构建过程中,某些对象使用的算法可能多种多样, ...

  6. 李建忠设计模式——观察者模式

    1.观察者模式(Observer/Event) 1.动机 在软件构建过程中,需要为某些对象建立一种"通知依赖关系"--一个对象(目标)的状态发生改变,所有的依赖对象(观察者对象)都 ...

  7. 李建忠设计模式-组件协作模式-模板方法模式

    目录 1.前言 2.模板方法模式(Template Method) 1.动机 2.例子 3.定义 1.结构图 2.模板方法模式适用情形 3.模式特点 参考 1.前言 现代软件专业分工后的第一个结果是& ...

  8. 清华李建忠设计模式课程感想

    最近又看了一波设计模式的东西,又有一些新的认识,设计模式一般是重构到模式,模式不是一蹴而就的,很多最开始在实现产品经理的需求时,第一版是不太能识别模式的,当然如果后期的迭代需求方向明确也可做提前设计, ...

  9. 李建忠设计模式——桥模式

    目录 1.桥模式 1.动机 2.模式定义 3.结构图 4.模式的组成 2.实例 1.描述 2.代码实现 要点总结 参考: 1.桥模式 1.动机 由于某些类型的固有的实现逻辑,使得他们具有两个变化的维度 ...

最新文章

  1. itoa函数和atoi函数
  2. 了解React.js中数组子项的唯一键
  3. cookie放在请求头_Web安全:你必须知道的“Cookie安全”
  4. Mysql中的联合索引、前缀索引、覆盖索引
  5. 增加表空间大小的四种方法
  6. JavaScript学习笔记:AJAX基础
  7. 如何选择适合的数据分析软件
  8. 基于SSM开发的房屋租赁系统 JAVA
  9. 5.13 综合案例2.0-火焰检测系统(2.2版本接口有更新)
  10. Til the Cows Come Home-Poj2387(最短路)
  11. matlab统计字符个数,Matlab函数统计字符串中莫个字母含量
  12. Linux下安装MySQL、安装注意事项以及安装问题解决等(以腾讯云服务为主)
  13. 折腾黑苹果 - 制作四叶草CLOVER引导U盘
  14. USB Type-C和USB PD
  15. 关于win10 睡眠或关屏恢复后卡顿的问题
  16. bootstrap 轮播插件
  17. 服务器系统迁移服务收费,服务器数据库迁移也收费
  18. sublime text 光标移动行末/行首
  19. ibm服务器 t系列,IBMT
  20. Java后端面经-----MySQL面试中常见问题总结

热门文章

  1. 给OkHttp Client添加socks代理
  2. 软件开发项目经理职责
  3. android x86 arm64,Android 的ARM架构和X86架构
  4. P2327 [SCOI2005]扫雷 - 模拟
  5. A045_jQuery案例实战_BootStrap
  6. User-Agent详解
  7. 【图像分割】基于脉冲耦合神经网络实现图像分割附matlab代码
  8. 游戏技术汇:莉莉丝COO张昊解剖《刀塔传奇》开发经验心得
  9. 微信群创意活动_一小群制造商将大创意转变为用户社区
  10. Mac新手必备技巧之Excel不可错过的16个实用快捷键