前言
一、解释器模式要点
解释器模式:
如果一种特定的问题发生的频率足够高,该问题的各个实例可能就值得表达为一个简单语言中的句子,解释器通过解释这些句子来解决该问题。
满足以下条件可以使用解释器模式:
1.当有一个语言需要解释执行,并且你可将语言中的句子表示为一个抽象语法树时,可使用解释器模式
2.该语言文法简单
3.效率不是关键问题
二、模式主要结构与实例
1.类结构图
参与者:
AbstractExpression(抽象类):定义一套接口规范
TerminalExpression(具体类T):终结符表达式,即最小单位语句中的一个“词”
NonterminalExpression(具体类N):非终结符表达式,即多个终结表达式满足某个规则的聚合
Context:上下文,包含解释器之外的一些全局信息
Client:客户,构建或给定一个抽象的语法树,该语法树由T和G的实例装配而成,并调用解释器
2.实例
假设现有如下命令:
命令格式为"命令类型-参数1-参数2-参数3…",要求用解释器模式去完成这个需求,每个关键字之间用"-“分割开。
例如控制网络连接到某设备的命令如下"C-http-localhost-1883”
C-连接
其类图如下:
C++实现代码如下
#include <iostream>
#include <string.h>
#include <stdlib.h>
using namespace std;
/*http-localhost-1883&mqtt-localhost-8888*/
/*AbstractExpression类*/
class AbstractWord
{
public:
virtual void *literpret(void) = 0;
};
/*TerminalExpression类*/
class Word : public AbstractWord
{
char *word;
public:
Word(char *c)
{
/*这里省略一些参数检验*/
this->word = (char *)malloc(strlen(c) + 1);
strcpy(this->word, c);
}
~Word()
{
free(word);
}
void *literpret(void)
{
return (char *)word;
}
};
/*NonterminalExpression类*/
class ConnectCmd : public AbstractWord
{
AbstractWord *protocol;
AbstractWord *host;
AbstractWord *port;
public:
ConnectCmd(char *c){
/*这里省略一些参数检验,下面protocol、host、port的解析过程由于不是重点所以这里略*/
/*成功解析出参数
*/
this->protocol = new Word((char *)"http");
this->host = new Word((char *)"localhost");
this->port = new Word((char *)"1883");
};
~ConnectCmd(){
};
void *literpret(void)
{
/*do connect http-local-host-1883*/
cout << "connect http-localhost-1883" << endl;
return NULL;
};
};
/*NonterminalExpression类*/
class NetWorkCmd : public AbstractWord
{
AbstractWord *net_cmd;
public:
NetWorkCmd(char *c)
{
/*这里省略一些参数检验*/
switch (c[0])
{
case 'C':/*解析第一个控制字符*/
this->net_cmd = new ConnectCmd(c + 2);
break;
/*其他命令同理*/
default:
break;
};
};
void *literpret(void)
{
this->net_cmd->literpret();
return NULL;
};
};
int main()
{
char * cmd = (char *)"C-http-local-host-1883";
NetWorkCmd * net = new NetWorkCmd(cmd);
net->literpret();
return 0;
}
总结
解释器模式优点:
1、可扩展性比较好,灵活。 2、增加了新的解释表达式的方式。 3、易于实现简单文法。
解释器模式缺点:
1、可利用场景比较少。 2、对于复杂的文法比较难维护。 3、解释器模式会引起类膨胀。 4、解释器模式采用递归调用方法。