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

典型模式:解释器模式(Interpreter)

解释器模式

1.动机

在软件构建过程中,如果某一特定领域内的问题比较复杂,类似的结构不断重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。

2.作用

将特定领域问题表达为某种语法规则下的句子,然后构建一个解释器来解释这样的句子。

3.定义

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

4.代码

  1. //运用解释器模式后代码
  2. class Expression {
  3. public:
  4. virtual int interpreter(map<char, int> var)=;
  5. virtual ~Expression(){}
  6. };
  7. //变量表达式
  8. class VarExpression: public Expression {
  9. char key;
  10. public:
  11. VarExpression(const char& key)
  12. {
  13. this->key = key;
  14. }
  15. int interpreter(map<char, int> var) override {
  16. return var[key];
  17. }
  18. };
  19. //符号表达式
  20. class SymbolExpression : public Expression {
  21. // 运算符左右两个参数
  22. protected:
  23. Expression* left;
  24. Expression* right;
  25. public:
  26. SymbolExpression( Expression* left, Expression* right):
  27. left(left),right(right){
  28.  
  29. }
  30. };
  31. //加法运算
  32. class AddExpression : public SymbolExpression {
  33. public:
  34. AddExpression(Expression* left, Expression* right):
  35. SymbolExpression(left,right){
  36.  
  37. }
  38. int interpreter(map<char, int> var) override {
  39. return left->interpreter(var) + right->interpreter(var);
  40. }
  41. };
  42. //减法运算
  43. class SubExpression : public SymbolExpression {
  44. public:
  45. SubExpression(Expression* left, Expression* right):
  46. SymbolExpression(left,right){
  47.  
  48. }
  49. int interpreter(map<char, int> var) override {
  50. return left->interpreter(var) - right->interpreter(var);
  51. }
  52. };
  53. Expression* analyse(string expStr) {
  54. stack<Expression*> expStack;
  55. Expression* left = nullptr;
  56. Expression* right = nullptr;
  57. for(int i=; i<expStr.size(); i++)
  58. {
  59. switch(expStr[i])
  60. {
  61. case '+':
  62. // 加法运算
  63. left = expStack.top();
  64. right = new VarExpression(expStr[++i]);
  65. expStack.push(new AddExpression(left, right));
  66. break;
  67. case '-':
  68. // 减法运算
  69. left = expStack.top();
  70. right = new VarExpression(expStr[++i]);
  71. expStack.push(new SubExpression(left, right));
  72. break;
  73. default:
  74. // 变量表达式
  75. expStack.push(new VarExpression(expStr[i]));
  76. }
  77. }
  78. Expression* expression = expStack.top();
  79. return expression;
  80. }
  81. void release(Expression* expression){
  82. //释放表达式树的节点内存...
  83. }
  84. int main(int argc, const char * argv[]) {
  85. string expStr = "a+b-c+d-e";
  86. map<char, int> var;
  87. var.insert(make_pair('a',));
  88. var.insert(make_pair('b',));
  89. var.insert(make_pair('c',));
  90. var.insert(make_pair('d',));
  91. var.insert(make_pair('e',));
  92. Expression* expression= analyse(expStr);
  93. int result=expression->interpreter(var);
  94. cout<<result<<endl;
  95. release(expression);
  96. return ;
  97. }
  98. pState->Operation1();
  99. pState = pState->pNext;
  100. //...
  101. }
  102. void Operation2(){
  103. //...
  104. pState->Operation2();
  105. pState = pState->pNext;
  106. //...
  107. }
  108. void Operation3(){
  109. //...
  110. pState->Operation3();
  111. pState = pState->pNext;
  112. //...
  113. }
  114. };

5.结构

其中,

1.AbstractExpression(抽象表达式 如):声明一个抽象的解释操作,这个接口为抽象语法树中所有的节点所共享;

2.TerminalExpression(终结符表达式 如):实现与文法中的终结符相关联的解释操作;一个句子中的每个终结符需要该类的一个实例。

3.NonterminalExpression(非终结符表达式):对文法中的每一条规则R::=R1R2…R3都需要一个NonterminalExpression类;为从R1到Rn的每个符号都维护一个AbstractExpression类型的实例变量;为文法中的非终结符实现解释操作,解释一般要递归调用表示R1到Rn的那些对象的解释操作。

4.Context(上下文):包含解释器之外的一些全局信息。

5.Client(客户):构建表示该文法定义的语言中一个特定的句子的抽象语法树。该抽象语法树由TerminalExpression和NonterminalExpression的实例装配而成。

6.总结

1.Interpret模式的应用场合是Interpret模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”,才适合使用Interpret模式。

2.使用Interpret模式来表示文法规则,从而可以使用面向对象技巧来方便的扩展文法。

3.Interpret模式比较适合简单的文法表示,对于复杂的文法表示,Interpret模式会产生比较大的类层次结构,需要求助于语法分析器这样的标准工具。

学习记录:《C++设计模式——李建忠主讲》7.“领域规则”模式的更多相关文章

  1. 学习记录:《C++设计模式——李建忠主讲》6.“状态变化”模式

    状态变化模式:在组件构建过程中,某些对象的状态经常面临变化,如何对这些变化进行有效的管理?同时又维持高层模块的稳定.状态变化模式为这一问题提供了一种解决方案. 典型模式:状态模式(State).备忘录 ...

  2. 学习记录:《C++设计模式——李建忠主讲》1.设计模式

    1.学习目标 1)理解松耦合设计思想: 2)掌握面向对象设计原则: 3)掌握重构技法改善设计: 4)掌握GOF核心设计模式: 2.定义 每个设计模式描述了一个在我们周围不断重复发生的问题,以及该问题解 ...

  3. 学习记录:《C++设计模式——李建忠主讲》2.面向对象设计原则

    1.课程内容: 重新认识面向对象:面向对象设计原则: 2.重新认识面向对象 1)理解隔离变化:从宏观层面来看,面向对象的构建方式更能适应软件的变化,将变化所带来的影响减为最小: 2)各司其职:从微观层 ...

  4. 学习记录:《C++设计模式——李建忠主讲》3.“组件协作”模式

    “组件协作”模式:现代软件专业分工之后的第一个结果是“框架与应用程序的划分”,“组件协作”模式通过晚期绑定,来实现框架与应用程序之间的松耦合,是二者之间协作时常用的模式.典型模式:Template M ...

  5. 学习记录:《C++设计模式——李建忠主讲》5.“对象性能”模式

    对象性能模式:面向对象很好地解决了抽象地问题,但是必不可免地要付出一定地代价.对于通常情况来讲,面向对象地成本大都可以忽略不计,但某些情况,面向对象所带来地成本必须谨慎处理. 典型模式:单件模式(Si ...

  6. 学习记录:《C++设计模式——李建忠主讲》4.“单一职责”模式

    单一职责模式:在软件组件的设计中,如果责任划分的不清晰,使用继承得到的结果往往是随着需求的变化,子类急剧膨胀,同时充斥着重复代码,这时候的关键是划清责任. 典型模式:装饰模式(Decorator).桥 ...

  7. 工厂模式(整理自李建忠<C++设计模式>视频)

    整理自李建忠<C++设计模式>视频 一.导入:"对象创建"模式和工厂模式 工厂模式只是该模式下的一种. 二.举例说明 有这样一个场景:需要在MainForm中设计一个按 ...

  8. 设计模式---领域规则模式之解析器模式(Interpreter)

    前提:领域规则模式 在特定领域内,某些变化虽然频繁,但可以抽象为某种规则.这时候,结合特定领域,将问题抽象为语法规则,从而给出该领域下的一般性解决方案. 典型模式 解析器模式:Interpreter ...

  9. Java设计模式学习记录-GoF设计模式概述

    前言 最近要开始学习设计模式了,以前是偶尔会看看设计模式的书或是在网上翻到了某种设计模式,就顺便看看,也没有仔细的学习过.前段时间看完了JVM的知识,然后就想着JVM那么费劲的东西都看完了,说明自己学 ...

随机推荐

  1. flutter 踩坑小计: amap_base 地图缩放 zoom 设置无效的问题

    这种问题估计也就我这种菜鸡能遇到了,因为我问了一些大佬,他们完全没遇到这类的问题. 如果你也遇到了,希望这篇文章能帮到你,倘若还不能解决你的问题,可以留言,我们共同研究. 问题:同样的插件,为什么偏偏 ...

  2. driud 异常

    异常如下: 十二月 25, 2017 11:37:14 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin警告: [SetProper ...

  3. Chrome远程调试之WebSocket

    var ws = new WebSocket('ws://localhost:9222/devtools/page/3c5c05fa-80b7-4cfe-8d1d-ebe79a7a5730');ws. ...

  4. Bootstrap selectpicker 下拉框多选获取选中value和多选获取文本值

    1.页面代码: 页面引入: bootstrap-select.min.css和 bootstrap-select.min.js. defaults-zh_CN.min.js文件,并初始化下拉选项框. ...

  5. centos7--zabbix3.4微信报警

    1.申请企业微信 1.1 注册企业微信的地址 https://qy.weixin.qq.com/ 1.2 按照提示进行填写 1.3 完善个人信息: 1.4 创建应用 根据提示创建应用: 1.5 筛出重 ...

  6. 升级springboot导致的业务异步回调积压问题定位

    1. 起因 A与B云侧模块特性联调的过程中,端侧发现云侧返回有延迟的情况. 7月19日与A模块一起抓包初步判断,B业务有积压的情况. 7月18日已经转侧B业务现网版本,由于使用一套逻辑.故可能存在请求 ...

  7. intellij idea tomcat 启动不生成war包

    intellij idea tomcat 启动不生成war包 想把项目打包成war包做测试,但是按照之前的方法居然没有成功导出war包,犯了很低级的错误,特此记录. (1)首先在Project Str ...

  8. java判断A字符串中是否包含B字符

    java.lang.String类提供的方法 public boolean contains(CharSequence s) 当且仅当此字符串包含指定的 char 值序列时,返回 true. 例如: ...

  9. Linux 限制IP——/etc/hosts.allow和/etc/hosts.deny文件【转】

    就像是 限制特定IP来访 想法 看起来通常的做法是利用hosts的拒绝设置,而它的设置是针对某一个具体的进程,具体的服务,在这里就是sshd了 看起来设置一个网段使用的是 x.x.x.0/24 后面加 ...

  10. 用google translate大文件

    问题: google translate对于大文件不支持,咋办? 思路:自己写个函数把的文件拆成小文件,再用google translate! code: from googletrans impor ...