23种设计模式(23)--Interpreter模式
2016-05-24 16:43
429 查看
平心而论,之前的22个设计模式大多都是比较常见的,几乎做任何项目都有使用的价值。然而这个Interpreter模式则不然,其适用范围较小。正如其名,此模式大多用来解释一些(自定义的)独特语法,例如某些游戏开发引擎中读取XML文件,或是WindowsPhone开发中的XAML文件,都是使用此模式来进行的。与其说是一种模式,不如说是一种具有通用规范的行为更为准确。
一个简单的例子:一份密码电报,需要通过特定的解读顺序以及某些关键字来解读,才可以获取其内容,而此模式即是大抵如此。
【核心】通过解释器来解释某种特定语法。
UML图:
这里有必要解释一下UML图:
Interpret方法即是解释器本身的行为。
TerminalExpression是终止符表达式,例如A◎B这个表达式中的A,B即是终止符。
NonterminalExpression是非终止符表达式,上式中的◎符号即为非终止符。
Context就是上下文啦,也就是需要被解释的东西。
【大致思路】
string类型的加密电报作为Context传入NonterminalExpression中,
其被后者通过Interpreter方法进行解释,
并输出密码。
Interpreter.h
[cpp] view
plain copy
#ifndef _INTERPRETER_H_
#define _INTERPRETER_H_
#include<string>
typedef std::string Context ;
class AbstractExpression
{
public:
AbstractExpression(){}
~AbstractExpression(){}
virtual void Interpreter(const Context& context)=0;
};
class TerminalExpression : public AbstractExpression
{
public:
TerminalExpression(char kc);
~TerminalExpression(){}
virtual void Interpreter(const Context& context);
private:
char keyChar;
};
class NonterminalExpression : public AbstractExpression
{
public:
NonterminalExpression(AbstractExpression* ae);
~NonterminalExpression(){}
virtual void Interpreter(const Context& context);
private:
AbstractExpression* terminalExpression;
};
#endif
Interpreter.cpp
[cpp] view
plain copy
#include "Interpreter.h"
#include<iostream>
TerminalExpression::TerminalExpression(char kc)
{
keyChar = kc;
}
void TerminalExpression::Interpreter(const Context& context)
{
int length = 0;
while (context[length] != '\0')
{
length++;
}
int numberArray[100];
int index = 0;
for(int i = 0;i < length;i++)
{
if(keyChar == context[i])
numberArray[index++] = i;
}
for(int i = 0;i < index;i++)
{
std::cout<<numberArray[i];
}
std::cout<<std::endl;
}
NonterminalExpression::NonterminalExpression(AbstractExpression* ae)
{
terminalExpression = ae;
}
void NonterminalExpression::Interpreter(const Context& context)
{
std::cout<<"The password is: ";
terminalExpression->Interpreter(context);
}
main.cpp
[cpp] view
plain copy
#include "Interpreter.h"
#include<iostream>
using namespace std;
int main()
{
AbstractExpression* terminal = new TerminalExpression('c');
AbstractExpression* nonTerminal = new NonterminalExpression(terminal);
//First test.
string contextFirst = "character of the cars in this chart.";
cout<<"Context: "<<contextFirst<<endl;
nonTerminal->Interpreter(contextFirst);
cout<<endl;
//Second test.
terminal = new TerminalExpression('o');
nonTerminal = new NonterminalExpression(terminal);
string contextSecond = "Thanks everyone for your long time supporting.";
cout<<"Context: "<<contextSecond<<endl;
nonTerminal->Interpreter(contextSecond);
return 0;
}
输出结果:
【注意事项】
嘿嘿,笔者稍微有点偷懒了。使用typedef将string包装为Context。其实真正的Context应该是一个独立类的哦。
在TerminalExpression的构造器中传入的字符就是解码的关键啦。其实正如前文所说,这个设计模式更加注重内部的行为,因此这段代码最重要的应当是TerminalExpression的Interpreter部分。不过也许会有读者问,为何NonterminalExpression的Interpreter部分非常简单,这是因为,非终止符只是作为一种行为的解释,真正的逻辑应当由终止符自己进行的。当然,由于解释器没有统一的形式与逻辑,因此具体的做法还是因程序而异啦。
转自:http://blog.csdn.net/elezeor/article/details/8643758
一个简单的例子:一份密码电报,需要通过特定的解读顺序以及某些关键字来解读,才可以获取其内容,而此模式即是大抵如此。
【核心】通过解释器来解释某种特定语法。
UML图:
这里有必要解释一下UML图:
Interpret方法即是解释器本身的行为。
TerminalExpression是终止符表达式,例如A◎B这个表达式中的A,B即是终止符。
NonterminalExpression是非终止符表达式,上式中的◎符号即为非终止符。
Context就是上下文啦,也就是需要被解释的东西。
【大致思路】
string类型的加密电报作为Context传入NonterminalExpression中,
其被后者通过Interpreter方法进行解释,
并输出密码。
Interpreter.h
[cpp] view
plain copy
#ifndef _INTERPRETER_H_
#define _INTERPRETER_H_
#include<string>
typedef std::string Context ;
class AbstractExpression
{
public:
AbstractExpression(){}
~AbstractExpression(){}
virtual void Interpreter(const Context& context)=0;
};
class TerminalExpression : public AbstractExpression
{
public:
TerminalExpression(char kc);
~TerminalExpression(){}
virtual void Interpreter(const Context& context);
private:
char keyChar;
};
class NonterminalExpression : public AbstractExpression
{
public:
NonterminalExpression(AbstractExpression* ae);
~NonterminalExpression(){}
virtual void Interpreter(const Context& context);
private:
AbstractExpression* terminalExpression;
};
#endif
Interpreter.cpp
[cpp] view
plain copy
#include "Interpreter.h"
#include<iostream>
TerminalExpression::TerminalExpression(char kc)
{
keyChar = kc;
}
void TerminalExpression::Interpreter(const Context& context)
{
int length = 0;
while (context[length] != '\0')
{
length++;
}
int numberArray[100];
int index = 0;
for(int i = 0;i < length;i++)
{
if(keyChar == context[i])
numberArray[index++] = i;
}
for(int i = 0;i < index;i++)
{
std::cout<<numberArray[i];
}
std::cout<<std::endl;
}
NonterminalExpression::NonterminalExpression(AbstractExpression* ae)
{
terminalExpression = ae;
}
void NonterminalExpression::Interpreter(const Context& context)
{
std::cout<<"The password is: ";
terminalExpression->Interpreter(context);
}
main.cpp
[cpp] view
plain copy
#include "Interpreter.h"
#include<iostream>
using namespace std;
int main()
{
AbstractExpression* terminal = new TerminalExpression('c');
AbstractExpression* nonTerminal = new NonterminalExpression(terminal);
//First test.
string contextFirst = "character of the cars in this chart.";
cout<<"Context: "<<contextFirst<<endl;
nonTerminal->Interpreter(contextFirst);
cout<<endl;
//Second test.
terminal = new TerminalExpression('o');
nonTerminal = new NonterminalExpression(terminal);
string contextSecond = "Thanks everyone for your long time supporting.";
cout<<"Context: "<<contextSecond<<endl;
nonTerminal->Interpreter(contextSecond);
return 0;
}
输出结果:
【注意事项】
嘿嘿,笔者稍微有点偷懒了。使用typedef将string包装为Context。其实真正的Context应该是一个独立类的哦。
在TerminalExpression的构造器中传入的字符就是解码的关键啦。其实正如前文所说,这个设计模式更加注重内部的行为,因此这段代码最重要的应当是TerminalExpression的Interpreter部分。不过也许会有读者问,为何NonterminalExpression的Interpreter部分非常简单,这是因为,非终止符只是作为一种行为的解释,真正的逻辑应当由终止符自己进行的。当然,由于解释器没有统一的形式与逻辑,因此具体的做法还是因程序而异啦。
转自:http://blog.csdn.net/elezeor/article/details/8643758
相关文章推荐
- httpclient4.4的简单demo
- C/C++整理
- The type org.junit.runners.BlockJUnit4ClassRunner cannot be resolved. It is indirectly referenced fr
- 不同长度的数据进行位运算
- C/C++中的转义字符
- 查看目录的大小
- caffe学习(3)------caffe训练日志
- 用AVAudioRecorder录音,AVAudioPlayer播放声音很小
- 怎么将ppt转换成word文件格式
- 线段树--单点更新
- scala编译的class字节码实现
- FFprobe使用指南
- 单链表实现多项式的相乘-c语言
- android开发环境搭建
- HBase Compaction流程
- 变态跳台阶,最终导向HDU_5698_瞬间移动
- VMware12+Ubuntu16.04 安装 以及全屏的实现
- GCD基础
- 1.处理屏幕触摸(单点触摸)
- 视图添加移动手势