设计模式---领域规则模式之解析器模式(Interpreter)
前提:领域规则模式
在特定领域内,某些变化虽然频繁,但可以抽象为某种规则。这时候,结合特定领域,将问题抽象为语法规则,从而给出该领域下的一般性解决方案。
典型模式
解析器模式:Interpreter
一:解释器模式Interpreter
(一)概念
一些应用提供了内建(Build-In)的脚本或者宏语言来让用户定义他们能够在系统中进行的操作。
Interpreter模式的目的就是使用一个解释器为用户提供一个一门定义语言的语法表示的解释器,然后通过解释器来解释语言中的句子。
Interpreter模式提供了一个实现语法解释器的框架。
(二)动机
在软件构建过程中,如果某一特定领域的问题比较复杂,类似的结构不断的重复出现,如果使用普通的编程方式来实现将面临非常频繁的变化。
在这种情况下,将特定领域的问题表达为某种语法规则下的句子,然后构建一个解析器来解释这样的句子,从而达到解决问题的目的。
(三)代码分析(加减运算)
利用操作树来实现语法规则提取
string expStr = "a+b-c+d"; //使用表达式树来表示规则

0.表达式基类
class Expression {
public:
virtual int interpreter(map<char, int> var)=0; //解析结果
virtual ~Expression(){}
};
1.构建变量表达式(叶子结点)
//变量表达式
class VarExpression: public Expression { char key; public:
VarExpression(const char& key)
{
this->key = key;
} int interpreter(map<char, int> var) override {
return var[key];
}
};
2.符号表达式(树结点基类)
//符号表达式
class SymbolExpression : public Expression { // 运算符左右两个参数
protected:
Expression* left;
Expression* right; public:
SymbolExpression( Expression* left, Expression* right):
left(left),right(right){
} };
3.符号表达式子类实现(树结点),进行执行
//加法运算
class AddExpression : 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 SymbolExpression { public:
SubExpression(Expression* left, Expression* right):
SymbolExpression(left,right){ }
int interpreter(map<char, int> var) override {
return left->interpreter(var) - right->interpreter(var);
} };
4.解析表达式(获取的是解析的表达式,不是结果)
Expression* analyse(string expStr) {
stack<Expression*> expStack; //使用栈来存储表达式
Expression* left = nullptr;
Expression* right = nullptr;
for(int i=; 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 VarExpression(expStr[i])); //不是符号,我们就进行入栈操作
}
}
Expression* expression = expStack.top(); //获取最后栈顶表达式返回出去就是结果
return expression;
}
5.表达式树构建
int main(int argc, const char * argv[]) {
string expStr = "a+b-c+d-e"; //结构类似,容易抽象为语法规则,业务频繁变化
map<char, int> var;
var.insert(make_pair('a',));
var.insert(make_pair('b',));
var.insert(make_pair('c',));
var.insert(make_pair('d',));
var.insert(make_pair('e',));
Expression* expression= analyse(expStr);
int result=expression->interpreter(var); //使用解析得到的表达式,可以获取结果返回
cout<<result<<endl;
release(expression);
return ;
}
6.释放空间,释放顺序下至上
void release(Expression* expression){
//释放表达式树的节点内存...
}
(四)模式定义
给定一个语言,定义它的文法的一种表示,并定义一种解释器,这个解释器使用该表示来解释语言中的句子。
——《设计模式》GoF
(五)类图(结构)

(六)要点总结
(一)Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”才适合使用Interpreter模式。
(二)使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法。
(三)Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interpreter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具。
(七)案例实现(没有上面讲解使用的案例好)
#include <iostream>
using namespace std;
#include "string" class Context
{
public:
Context(int num)
{
m_num = num;
}
public:
void setNum(int num)
{
m_num = num;
}
int getNum()
{
return m_num;
}
void setRes(int res)
{
m_res = res;
}
int getRes()
{
return m_res;
} private:
int m_num;
int m_res;
}; class Expression
{
public:
virtual void interpreter(Context *context) = ;
}; class PlusExpression:public Expression
{
public:
virtual void interpreter(Context *context)
{
int num = context->getNum();
num++;
context->setNum(num);
context->setRes(num);
}
}; class MinusExpression:public Expression
{
public:
virtual void interpreter(Context *context)
{
int num = context->getNum();
num--;
context->setNum(num);
context->setRes(num);
}
}; int main(void)
{
Context *pcxt = new Context(); Expression *e1 = new PlusExpression();
e1->interpreter(pcxt);
cout << "PlusExpression:" << pcxt->getRes() << endl; Expression *e2 = new MinusExpression();
e2->interpreter(pcxt);
cout << "MinusExpression:" << pcxt->getRes() << endl; delete e1;
delete e2; system("pause");
return ;
}

设计模式---领域规则模式之解析器模式(Interpreter)的更多相关文章
- Java进阶篇设计模式之五-----外观模式和装饰器模式
前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...
- Java设计模式之五 ----- 外观模式和装饰器模式
前言 在上一篇中我们学习了结构型模式的适配器模式和桥接模式.本篇则来学习下结构型模式的外观模式和装饰器模式. 外观模式 简介 外观模式隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口.这 ...
- 深入探索Java设计模式(三)之装饰器模式
装饰器模式使你可以在运行时使用类似于对象组成的技术来装饰类.这在我们希望实例化具有新职责的对象而无需对基础类进行任何代码更改的情况下尤其有用.本文是在学习完优锐课JAVA架构VIP课程—[框架源码专题 ...
- dom4j解析器 基于dom4j的xpath技术 简单工厂设计模式 分层结构设计思想 SAX解析器 DOM编程
*1 dom4j解析器 1)CRUD的含义:CreateReadUpdateDelete增删查改 2)XML解析器有二类,分别是DOM和SAX(simple Api for xml). ...
- 设计模式---对象创建模式之构建器模式(Builder)
一:概念 Builder模式也叫建造者模式或者生成器模式,是由GoF提出的23种设计模式中的一种.Builder模式是一种对象创建型模式之一,用来隐藏复合对象的创建过程,它把复合对象的创建过程加以抽象 ...
- IOS设计模式之二(门面模式,装饰器模式)
本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq) ...
- 设计模式---行为变化模式之访问器模式(Visitor)
一:概念 访问者模式,是行为模式之一,它分离对象的数据和行为,使用Visitor模式,可以不修改已有类的情况下,增加新的操作角色和职责. 二:动机 在软件构建的过程中,由于需求的改变,某些类层次结构中 ...
- 面向对象程序设计(OOP设计模式)-结构型模式之装饰器模式的应用与实现
课程名称:程序设计方法学 实验4:OOP设计模式-结构型模式的应用与实现 时间:2015年11月18日星期三,第3.4节 地点:理1#208 一.实验目的 加深对结构型设计模式的理解以及在开发中的实际 ...
- Java设计模式(七)Decorate装饰器模式
一.场景描述 (一)问题 系统中最初使用Crystal Report(水晶报表)工具生成报表,并将报表发送给客户端查看,此时定义一CrystalReport工具类即可完成水晶报表的生成工作. 后续报表 ...
随机推荐
- 图片文字识别aip的一个小Demo
目前接触到了一个新的内容,识别图片上的文字,以下是这个Demo 首先需要在需要在百度云-管理中心创建应用 地址:http://console.bce.baidu.com/ai/#/ai/ocr/app ...
- Linux qemu-nbd mount qemu disk image
Linux qemu-nbd mount qemu disk image deepin@deepin:~$ deepin@deepin:~$ qemu-nbd --help Usage: qemu-n ...
- 【HDU - 4345 】Permutation(DP)
BUPT2017 wintertraining(15) #8F 题意 1到n的排列,经过几次置换(也是一个排列)回到原来的排列,就是循环了. 现在给n(<=1000),求循环周期的所有可能数. ...
- nagios 监控内存使用情况
监控本机内存cd /usr/lib64/nagios/pluginstouch check_mem.sh #!/bin/bash " ]; then memTotal_b=`free -b ...
- Android GPS定位测试(附效果图)
今天因为工作需要,把以前编写的一个GPS测试程序拿出来重新修改了一下.这个程序说起来有些历史了,是我11年编写的,那时候学了Android开发没多久,算是一个实验性的作品.现在工作需要,重新拿出来修整 ...
- 自写juqery插件实现左右循环滚动效果图
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xht ...
- MOSFET的半桥驱动电路设计要领详解
1 引言 MOSFET凭开关速度快.导通电阻低等优点在开关电源及电机驱动等应用中得到了广泛应用.要想使MOSFET在应用中充分发挥其性能,就必须设计一个适合应用的最优驱动电路和参数.在应用中MOSFE ...
- Learn to securely share files on the blockchain with IPFS!
https://medium.com/@mycoralhealth/learn-to-securely-share-files-on-the-blockchain-with-ipfs-219ee47d ...
- navicat primium 快捷键与命令
1.ctrl+q 打开查询窗口 2.ctrl+/ 注释sql语句 3.ctrl+shift +/ 解除注释 4.ctrl+r 运行查询窗口的s ...
- A1042. Shuffling Machine
Shuffling is a procedure used to randomize a deck of playing cards. Because standard shuffling techn ...