现在的位置: 首页 > 综合 > 正文

【2013.3.6】真正的设计模式无需解释,而在心中,在领悟。——Interpreter

2018年10月09日 ⁄ 综合 ⁄ 共 2754字 ⁄ 字号 评论关闭

// // // // // // // // //

///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

Interpreter.cpp

#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

#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部分非常简单,

这是因为,

非终止符只是作为一种行为的解释,

真正的逻辑应当由终止符自己进行的。

当然,

由于解释器没有统一的形式与逻辑,

因此具体的做法还是因程序而异啦。

抱歉!评论已关闭.