0%

设计模式之职责链和解析器

设计模式基础(13):职责链&解析器

包含职责链&解析器两种模式中的C++示例代码、面向的问题、图解两种模式核心思想

职责链

面向的需求

请求&处理对象的解耦合,当有多个处理对象,但是只有某一个处理具体请求。可采用职责链模式。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <string>
using namespace std;
enum class RequestType
{
REQ_HANDLER1,
REQ_HANDLER2,
REQ_HANDLER3
};

class Reqest
{
string description;
RequestType reqType;
public:
Reqest(const string & desc, RequestType type) : description(desc), reqType(type) {}
RequestType getReqType() const { return reqType; }
const string& getDescription() const { return description; }
};

class ChainHandler{
ChainHandler *nextChain;
void sendReqestToNextHandler(const Reqest & req)
{
if (nextChain != nullptr)
nextChain->handle(req);
}
protected:
virtual bool canHandleRequest(const Reqest & req) = 0;
virtual void processRequest(const Reqest & req) = 0;
public:
ChainHandler() { nextChain = nullptr; }
void setNextChain(ChainHandler *next) { nextChain = next; }

void handle(const Reqest & req)
{
if (canHandleRequest(req))
processRequest(req);
else
sendReqestToNextHandler(req);
}
};

class Handler1 : public ChainHandler{
protected:
bool canHandleRequest(const Reqest & req) override
{
return req.getReqType() == RequestType::REQ_HANDLER1;
}
void processRequest(const Reqest & req) override
{
cout << "Handler1 is handle reqest: " << req.getDescription() << endl;
}
};

class Handler2 : public ChainHandler{
protected:
bool canHandleRequest(const Reqest & req) override
{
return req.getReqType() == RequestType::REQ_HANDLER2;
}
void processRequest(const Reqest & req) override
{
cout << "Handler2 is handle reqest: " << req.getDescription() << endl;
}
};

class Handler3 : public ChainHandler{
protected:
bool canHandleRequest(const Reqest & req) override
{
return req.getReqType() == RequestType::REQ_HANDLER3;
}
void processRequest(const Reqest & req) override
{
cout << "Handler3 is handle reqest: " << req.getDescription() << endl;
}
};

int main(){
Handler1 h1; Handler2 h2; Handler3 h3;
h1.setNextChain(&h2); h2.setNextChain(&h3);

Reqest req("process task ... ", RequestType::REQ_HANDLER3);
h1.handle(req);
return 0;
}

代码思想图示

职责链

关键点

  • 注意职责链的构建,逻辑上的传递。

解析器

面向的需求

  • 将某些变化非常频繁的领域表达为某种语法规则下的句子,然后采用一套通用的规则来处理这些语句。

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#include <iostream>
#include <map>
#include <stack>

using namespace std;

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* left, Expression* right):
left(left),right(right){

}

};

//加法运算
class AddExpression : public SymbolExpression {

public:
AddExpression(Expression* left, Expression* right):
SymbolExpression(left,right){

}
int interpreter(map<char, int> var) override {
return left->interpreter(var) + right->interpreter(var);
}

};

//减法运算
class SubExpression : public SymbolExpression {

public:
SubExpression(Expression* left, Expression* right):
SymbolExpression(left,right){

}
int interpreter(map<char, int> var) override {
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 SubExpression(left, right));
break;
default:
// 变量表达式
expStack.push(new VarExpression(expStr[i]));
}
}

Expression* expression = expStack.top();

return expression;
}

void release(Expression* expression){

//释放表达式树的节点内存...
}

int main(int argc, const char * argv[]) {


string expStr = "a+b-c+d-e";
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));
var.insert(make_pair('e',10));


Expression* expression= analyse(expStr);

int result=expression->interpreter(var);

cout<<result<<endl;

release(expression);

return 0;
}

代码思想图示

解析器

关键点

  • 明确解析器模式只适用于变化频繁且规则相对简单的情况
  • 当语法规则繁琐时,面向对象的类图关系将非常复杂。当前多采用语法分析生成器这样的标准工具