C++设计模式总结-汇总了全部23种设计模式的详细说明
第23种:解释器模式
解释器模式(Interpreter Pattern)是一种行为型设计模式,其核心思想是为特定领域语言(DSL)定义语法规则,并构建一个解释器来解析和执行该语言的句子。它是通过将复杂的语言结构分解为简单的表达式,并通过组合这些表达式来处理更复杂的逻辑。
这种模式的灵感来源于编译原理中的词法分析和语法解析过程。例如:
解释器模式通过以下方式来实现设计目标:
解释器模式包含以下核心角色:
举一个典型的类结构,如下:
class Expression {
public:
virtual ~Expression() = default;
virtual int interpret() = 0;
};
class NumberExpression : public Expression {
public:
NumberExpression(int value) : m_value(value) {}
int interpret() override { return m_value; }
private:
int m_value;
};
class AddExpression : public Expression {
public:
AddExpression(Expression* left, Expression* right)
: m_left(left), m_right(right) {}
int interpret() override {
return m_left->interpret() + m_right->interpret();
}
private:
Expression* m_left;
Expression* m_right;
};
解释器模式的核心是构建抽象语法树(AST):
示例:如何解析 “3 + 5 * 2”
// 构建语法树
Expression* expr = new AddExpression(
new NumberExpression(3),
new MultiplyExpression(
new NumberExpression(5),
new NumberExpression(2)
)
);
解释过程分为三个阶段:
关键代码示例:
class Context {
public:
int getVariableValue(const std::string& name) {
// 从变量表获取值
return m_variables[name];
}
void setVariableValue(const std::string& name, int value) {
m_variables[name] = value;
}
private:
std::map<std::string, int> m_variables;
};
class VariableExpression : public Expression {
public:
VariableExpression(const std::string& name) : m_name(name) {}
int interpret(Context& context) override {
return context.getVariableValue(m_name);
}
private:
std::string m_name;
};
C++ 中通过组合非终结符表达式实现:
class ExpressionParser {
public:
Expression* parse(const std::string& input) {
// 词法分析
std::vector<Token> tokens = lex(input);
// 语法分析
return parseExpression(tokens);
}
private:
Expression* parseExpression(std::vector<Token>& tokens);
Expression* parseTerm(std::vector<Token>& tokens);
Expression* parseFactor(std::vector<Token>& tokens);
};
案例 1:数学表达式计算器
// 解析表达式"10 + 20 * 3"
ExpressionParser parser;
Expression* expr = parser.parse("10 + 20 * 3");
Context context;
int result = expr->interpret(context); // 70
案例 2:业务规则引擎
// 规则:年龄>18且收入>5000
Expression* rule = new AndExpression(
new GreaterThanExpression("age", 18),
new GreaterThanExpression("income", 5000)
);
Context context;
context.setVariableValue("age", 25);
context.setVariableValue("income", 6000);
bool result = rule->interpret(context); // true
当系统满足以下条件时,适合使用解释器模式:
定义文法规则
condition ::= ( variable OP value ) ( AND/OR condition )*
OP ::= > | < | == | !=
创建抽象表达式类
class ConditionExpression {
public:
virtual bool interpret(Context& context) = 0;
virtual ~ConditionExpression() = default;
};
实现终结符表达式
class VariableExpression : public ConditionExpression {
public:
VariableExpression(const std::string& name) : m_name(name) {}
bool interpret(Context& context) override {
return context.hasVariable(m_name);
}
private:
std::string m_name;
};
实现非终结符表达式
class GreaterThanExpression : public ConditionExpression {
public:
GreaterThanExpression(const std::string& var, int val)
: m_var(var), m_val(val) {}
bool interpret(Context& context) override {
return context.getVariable(m_var) > m_val;
}
private:
std::string m_var;
int m_val;
};
构建复合表达式
ConditionExpression* rule = new AndExpression(
new GreaterThanExpression("age", 18),
new OrExpression(
new EqualExpression("role", "admin"),
new GreaterThanExpression("income", 5000)
)
);
执行解释过程
Context context;
context.setVariable("age", 25);
context.setVariable("role", "user");
context.setVariable("income", 6000);
bool result = rule->interpret(context); // true
示例:模板化比较表达式
template<typename T>
class CompareExpression : public ConditionExpression {
public:
CompareExpression(const std::string& var, T val, CompareOp op)
: m_var(var), m_val(val), m_op(op) {}
bool interpret(Context& context) override {
T actual = context.getVariable<T>(m_var);
switch(m_op) {
case GreaterThan: return actual > m_val;
case LessThan: return actual < m_val;
// ...其他比较操作
}
}
private:
std::string m_var;
T m_val;
CompareOp m_op;
};
方案 1:使用享元模式减少类实例
class ExpressionFactory {
public:
static Expression* createAddExpression() {
static AddExpression instance;
return &instance;
}
};
// 使用方式
Expression* addExpr = ExpressionFactory::createAddExpression();
方案 2:通过缓存来解释结果
class MemoizedExpression : public Expression {
public:
MemoizedExpression(Expression* expr) : m_expr(expr) {}
int interpret(Context& context) override {
auto key = context.getKey();
if (m_cache.find(key) == m_cache.end()) {
m_cache[key] = m_expr->interpret(context);
}
return m_cache[key];
}
private:
Expression* m_expr;
std::map<std::string, int> m_cache;
};
方案 3:引入解释器进行优化
附一个比较完整的代码示例
#include
#include
#include
#include
#include
using namespace std;
// 上下文类
class Context {
public:
int getVariable(const string& name) const {
return m_variables.count(name) ? m_variables.at(name) : 0;
}
void setVariable(const string& name, int value) {
m_variables[name] = value;
}
private:
map<string, int> m_variables;
};
// 抽象表达式
class Expression {
public:
virtual int interpret(Context& context) = 0;
virtual ~Expression() = default;
};
// 数字表达式
class NumberExpression : public Expression {
public:
NumberExpression(int value) : m_value(value) {}
int interpret(Context&) override { return m_value; }
private:
int m_value;
};
// 变量表达式
class VariableExpression : public Expression {
public:
VariableExpression(const string& name) : m_name(name) {}
int interpret(Context& context) override {
return context.getVariable(m_name);
}
private:
string m_name;
};
// 二元表达式
class BinaryExpression : public Expression {
public:
BinaryExpression(Expression* left, Expression* right)
: m_left(left), m_right(right) {}
~BinaryExpression() {
delete m_left;
delete m_right;
}
protected:
Expression* m_left;
Expression* m_right;
};
// 加法表达式
class AddExpression : public BinaryExpression {
public:
AddExpression(Expression* left, Expression* right)
: BinaryExpression(left, right) {}
int interpret(Context& context) override {
return m_left->interpret(context) + m_right->interpret(context);
}
};
// 乘法表达式
class MultiplyExpression : public BinaryExpression {
public:
MultiplyExpression(Expression* left, Expression* right)
: BinaryExpression(left, right) {}
int interpret(Context& context) override {
return m_left->interpret(context) * m_right->interpret(context);
}
};
// 表达式解析器
class ExpressionParser {
public:
Expression* parse(const string& input) {
vector<string> tokens = tokenize(input);
return parseExpression(tokens, 0);
}
private:
vector<string> tokenize(const string& input) {
vector<string> tokens;
stringstream ss(input);
string token;
while (ss >> token) {
tokens.push_back(token);
}
return tokens;
}
Expression* parseExpression(vector<string>& tokens, int& index) {
Expression* expr = parseTerm(tokens, index);
while (index < tokens.size() && isOperator(tokens[index])) {
string op = tokens[index++];
Expression* term = parseTerm(tokens, index);
expr = createExpression(op, expr, term);
}
return expr;
}
Expression* parseTerm(vector<string>& tokens, int& index) {
string token = tokens[index++];
if (isdigit(token[0])) {
return new NumberExpression(stoi(token));
} else {
return new VariableExpression(token);
}
}
bool isOperator(const string& token) {
return token == "+" || token == "*";
}
Expression* createExpression(const string& op, Expression* left, Expression* right) {
if (op == "+") return new AddExpression(left, right);
if (op == "*") return new MultiplyExpression(left, right);
throw invalid_argument("Unknown operator");
}
};
// 客户端代码
int main() {
ExpressionParser parser;
string input = "a + 5 * b";
Context context;
context.setVariable("a", 10);
context.setVariable("b", 20);
Expression* expr = parser.parse(input);
int result = expr->interpret(context); // 10 + 5*20 = 110
cout << "Result: " << result << endl;
delete expr;
return 0;
}