版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yzt629/article/details/89713635
1.解释模式的定义
解释器模式的官方定义,即“给定一个语言,定义它的一种表示方法,并定义一个解释器。这个解释器使用该表示来解析语言中的句子。”通俗点来说,可以理解为密码的密码文和解密编号,原输入的句子为一个语言,其需要通过使用定义在解释器中的对应的解密方式来进行加工处理,从而得到需要的句子。解释器可以有多种,以实现对于不同情况下语言的解释处理工作。
2.解释模式的类图
解释器模式的类图如图所示,Context环境类表示当前的文本环境,简单来说就是一段语句之类的的东西。而AbstreactExpression为解释器的抽象类,其中定义用于对当前文本环节Context的接口,而其余的实例解释器对象则实现这个接口,从而实现不同的解释器解释出的效果不同。
- Context环境类:其为解释器的解释对象输入类,其内部存储的数据以及需要解释的数据,均根据实际情况而定;
- AbstreactExpression解释器类:这是一个抽象类,其内部定义了实现解释过程的接口函数Interpret。当然也可以增加其他的功能函数;
- Expression解释器实例类:其继承自AbstractExpression解释器类,通过实现其中的Interpret接口,完成对解释器的解释功能的实现,并通过不同的解释器实例类中,函数接口实现的不同,实现解释器的不同;
- Client客户端:客户端只知道AbstreactExpression解释器类与Context环境类,在使用时,面向抽象类编程得到实例化的Expression解释器类,然后使用解释器对文本环境进行解释,得到所需要的结果。
3.解释模式的代码实现
本例所使用的情况较为简单,没有去实现密码解析类的功能,而是直接使用了前后缀添加的功能。
具体地说,本例中使用File文件类表示Context环境类,使用Add类表示AbstreactExpression解释器类,其中定义了接口add,表示添加的功能;而使用AddSuffix_jpg和AddPrefix_mike表示添加.jpg后缀名和添加的[mike]的前缀名,其即为实例化的Expression解释器实例类。整体的实现过程较为简单,在解释器类中直接实现Context类中的数据改变,改变的是传入的Context类自身的参数,而不是一个临时的Context修改后再覆盖。
#include <iostream>
#include <string>
using namespace std;
class File
{
public:
File(string name) : m_name(name) {}
void setname(string name)
{
m_name = name;
}
string getname()
{
return m_name;
}
private:
string m_name;
};
class Add
{
public:
virtual void add(File* file) = 0;
};
class AddPrefix_mike : public Add
{
public:
void add(File* file) override
{
string addprefix = "[Mike]" + file->getname();
file->setname(addprefix);
}
};
class AddSuffix_jpg : public Add
{
public:
void add(File* file) override
{
string addsuffix = file->getname() + ".jpg";
file->setname(addsuffix);
}
};
int main()
{
File* picture1 = new File("Messi");
File* picture2 = new File("James");
Add* addprefix1 = new AddPrefix_mike;
Add* addsuffix1 = new AddSuffix_jpg;
cout << "picture1's name is " << picture1->getname() << endl;
cout << "picture2's name is " << picture2->getname() << endl;
addprefix1->add(picture1);
addprefix1->add(picture2);
cout << "picture1's name is " << picture1->getname() << endl;
cout << "picture2's name is " << picture2->getname() << endl;
addsuffix1->add(picture1);
addsuffix1->add(picture2);
cout << "picture1's name is " << picture1->getname() << endl;
cout << "picture2's name is " << picture2->getname() << endl;
delete picture1;
delete picture2;
delete addprefix1;
delete addsuffix1;
return 0;
}