// // // // // // // // //
///2013.3.6
// // // // // // // // //
终于走到了设计模式的最后一个。
平心而论,
之前的22个设计模式大多都是比较常见的,
几乎做任何项目都有使用的价值。
然而这个Interpreter模式则不然,
其适用范围较小。
正如其名,
此模式大多用来解释一些(自定义的)独特语法,
例如某些游戏开发引擎中读取XML文件,
或是WindowsPhone开发中的XAML文件,
都是使用此模式来进行的。
与其说是一种模式,
不如说是一种具有通用规范的行为更为准确。
其简单的一个例子是:
斯摩格密码。
这是我起的名字,
大家也不用去搜索。
但是大致就是如此,
例如一份密码电报,
需要通过特定的解读顺序以及某些关键字来解读,
才可以获取其内容,
而此模式即是大抵如此。
【核心】通过解释器来解释某种特定语法。
UML图:
这里有必要解释一下UML图:
Interpret方法即是解释器本身的行为。
TerminalExpression是终止符表达式,例如A◎B这个表达式中的A,B即是终止符。
NonterminalExpression是非终止符表达式,上式中的◎符号即为非终止符。
Context就是上下文啦,也就是需要被解释的东西。
示例代码
【大致思路】
string类型的加密电报作为Context传入NonterminalExpression中,
其被后者通过Interpreter方法进行解释,
并输出密码。
Interpreter.h
#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
#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); }
#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部分非常简单,
这是因为,
非终止符只是作为一种行为的解释,
真正的逻辑应当由终止符自己进行的。
当然,
由于解释器没有统一的形式与逻辑,
因此具体的做法还是因程序而异啦。