领域规则模式
在特定领域中,某些变化虽然频繁,但可以抽象为某种规则。这时候,结合特定领域,将问题抽象为语法规则,从而给出在该领域下的一般性解决方案。
属于领域规则模式的有Interpreter
class Expression{
public:
virtual int interpreter(map<char, int> var) = 0;
virtual ~Expression() {}
};
// 变量表达式
class VarExpression : public Expression{
char key;
public:
VarExpression(const char &key){
this->key = key;
}
int interpreter(map<char, int> var) override{
return var[key];
}
}
// 符号表达式
class SymbolExpression : public Expression{
protected:
Expression *left;
Expression *right;
public:
SymbolExpression(Expression *x, Expression *y) : left(x), right(y) {}
}
class AddExpression : public SymbolExpression {
public:
AddExpression(Expression *x, Expression *y) : SymbolExpression(x,y) {}
int interpreter(map<char, int> var){
return left->interpreter(var) + right->interpreter(var);
}
}
class SubExpression : public SymbolExpression{
public:
SubExpression(Expression *x, Expression *y) : SymbolExpression(x,y) {}
int interpreter(map<char, int> var){
return left->interpreter(var) - right->interpreter(var);
}
};
Expression *analyse(string expStr){
stack<Expression *> expStack; // 这里的栈操作属实没什么意义,只要保留一份最顶上的元素即可。
Expression *left = nullptr;
Expression *right = nullptr;
for(int i = 0; i < expStr.size(); ++i){
switch( expStr[i] ){
case '+':
left = expStack.top();
right = new VarExpression(expStr[++i]);
expStack.push(new AddExpression(left, right) );
break;
case '-':
left = expStack.top();
right = new VarExpression(expStr[++i]);
expStack.push(new SubExpressionn(left, right) );
break;
default:
expStack.push(new VarExpression(expStr[i]));
}
}
Expression *expression = expStack.top();
return expression;
}
void release(Expression *exp){
// 释放表达式树的节点内存
}
int main(){
string expStr = "a+b-c+d"; // 这个可以任意加减下去
map<char, int> var;
var.insert(make_pair('a', 5) );
var.insert(make_pair('b', 2) );
var.insert(make_pair('c', 1) );
var.insert(make_pair('d', 6) );
Expression *expression = analyse(expStr); // 构建表达式树,并返回根节点
int result = expression->interpreter(var); // 根节点开始解析,会使用后序遍历的方式计算结果。
cout << result << endl;
}
要点总结:
– Interpreter模式的应用场合是Interpreter模式应用中的难点,只有满足“业务规则频繁变化,且类似的结构不断重复出现,并且容易抽象为语法规则的问题”才适合使用Interpreter模式
– 使用Interpreter模式来表示文法规则,从而可以使用面向对象技巧来方便地“扩展”文法
– Interpreter模式比较适合简单的文法表示,对于复杂的文法表示,Interpreter模式会产生比较大的类层次结构,需要求助于语法分析生成器这样的标准工具