一、解释器模式(Interpreter Pattern)提供了一种方法来定义语言的文法,然后用该语言写出来的句子可以被该语言解释器解释。在这种模式中,我们需要定义一个表达式接口,以及该接口的实现,它实现了解释操作。
以下是一个简单的解释器模式的实现,用于解释算术表达式:
#include <iostream>
#include <string>
#include <memory>
#include <map>
// 表达式基类
class Expression {
public:
virtual ~Expression() {}
virtual int interpret(std::map<std::string, int> &var) = 0;
};
// 变量表达式
class Variable : public Expression {
public:
Variable(std::string key) : key_(key) {}
int interpret(std::map<std::string, int> &var) override {
return var[key_];
}
private:
std::string key_;
};
// 常量表达式
class Constant : public Expression {
public:
Constant(int value) : value_(value) {}
int interpret(std::map<std::string, int> &var) override {
return value_;
}
private:
int value_;
};
// 加法表达式
class Addition : public Expression {
public:
Addition(std::shared_ptr<Expression> left, std::shared_ptr<Expression> right) : left_(left), right_(right) {}
int interpret(std::map<std::string, int> &var) override {
return left_->interpret(var) + right_->interpret(var);
}
private:
std::shared_ptr<Expression> left_, right_;
};
// 客户端代码
int main() {
// 定义变量
std::shared_ptr<Variable> a = std::make_shared<Variable>("a");
std::shared_ptr<Variable> b = std::make_shared<Variable>("b");
std::shared_ptr<Constant> c = std::make_shared<Constant>(3);
// 构建表达式 a + b
std::shared_ptr<Addition> expression = std::make_shared<Addition>(a, b);
// 解释表达式,设置变量值
std::map<std::string, int> context = {{"a", 5}, {"b", 10}};
int result = expression->interpret(context);
std::cout << "Result: " << result << std::endl; // 输出结果应该是 15
return 0;
}
在这个例子中,我们定义了一个表达式接口Expression
,以及三个实现了该接口的类:Variable
、Constant
和Addition
。Addition
类用于表示加法操作,它持有左右两个表达式的指针。interpret
方法被重写以执行加法操作。在客户端代码中,我们构建了一个表达式a + b
,并通过一个上下文(context
)来解释它,得到了a
和b
的和。
二、
解释器模式(不重要):
类行为型模式,定义语言的文法,建立一个解释器来解释该语言中的句子
解释器的结构:
(1)抽象表达式:声明抽象的解释操作,是终结符表达式和非终结符表达式的公共父类
(2)终结符表达式实现与文法中的终结符相关联的解释操作(叶子节点)
(3)非终结符表达式实现文法中非终结符的解释操作(非叶子节点)
(4)环境类(上下文类):存储解释器之外的一些全局信息
解释器模式的适用场景:
1.主要应用在面向对象语言开发的编译器和解释器设计
2.将一个需要执行语言中的句子表示为一个抽象语法树
3.文法较为简单的时候
解释器模式的优点:
1.易于改变和扩展文法
2.易于实现文法
3.增加新的文法表达式不需修改原有代码,符合开闭原则
解释器模式的缺点:
1.对于复杂的文法难以维护,包含太多文法规则会使表达式类增多,难以维护
2.使用了循环和递归,执行效率低
3.应用场景有限
比如:
#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) = 0;
};
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);
}
};
void main()
{
Context *pcxt = new Context(10);
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 e2;
delete e1;
system("pause");
return ;
}