PHP设计模式-责任链

适用性

  • 把一个对象传递到一个对象链上,直到有对象处理这个对象
  • 可以干什么:我们可以做一个filter,或者gateway

    代码示例

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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

/**
* 请求对象
*/
class Request
{
/**
* 请求对象身份标识
* @var string
*/
private $_requestId = '';

/**
* 魔术方法 设置私有属性
* @param string $name 属性名称
* @param string $value 属性值
*/
public function __set($name='', $value='')
{
$name = '_' . $name;
$this->$name = $value;
}

/**
* 魔术方法 获取私有属性
* @param string $name 属性名称
*/
public function __get($name='')
{
$name = '_' . $name;
return $this->$name;
}
}

/**
* handler抽象类
*/
abstract class Handler
{
/**
* 下一个hanler对象
* @var [type]
*/
private $_nextHandler;

/**
* 校验方法
*
* @param Request $request 请求对象
*/
abstract public function Check(Request $request);

/**
* 设置责任链上的下一个对象
*
* @param Handler $handler
*/
public function setNext(Handler $handler)
{
$this->_nextHandler = $handler;
return $handler;
}

/**
* 启动
*
* @param Handler $handler
*/
public function start(Request $request)
{
$this->check($request);
// 调用下一个对象
if (!empty($this->_nextHandler)) {
$this->_nextHandler->start($request);
}
}

}

/**
* handler接口
**/
class HandlerAccessToken extends Handler
{
/**
* 校验方法
*
* @param Request $request 请求对象
*/
public function Check(Request $request)
{
echo "请求{$request->requestId}: 令牌校验通过~ \n";
}
}

/**
* handler接口
*/
class HandlerArguments extends Handler
{
/**
* 校验方法
*
* @param Request $request 请求对象
*/
public function Check(Request $request)
{
echo "请求{$request->requestId}: 参数校验通过~ \n";
}
}

/**
* handler接口
*/
class HandlerAuthority extends Handler
{
/**
* 校验方法
*
* @param Request $request 请求对象
*/
public function Check(Request $request)
{
echo "请求{$request->requestId}: 权限校验通过~ \n";
}
}

/**
* handler接口
*/
class HandlerFrequent extends Handler
{
/**
* 校验方法
*
* @param Request $request 请求对象
*/
public function Check(Request $request)
{
echo "请求{$request->requestId}: 请求频率校验通过~ \n";
}
}

/**
* handler接口
*/
class HandlerSign extends Handler
{
/**
* 校验方法
*
* @param Request $request 请求对象
*/
public function Check(Request $request)
{
echo "请求{$request->requestId}: 签名校验通过~ \n";
}
}

try {
// 下面我们用责任链模式实现一个api-gateway即接口网关

// 初始化一个请求对象
$request = new Request();
// 设置一个请求身份id
$request->requestId = uniqid();

// 初始化一个:令牌校验的handler
$handlerAccessToken = new HandlerAccessToken();
// 初始化一个:访问频次校验的handler
$handlerFrequent = new HandlerFrequent();
// 初始化一个:必传参数校验的handler
$handlerArguments = new HandlerArguments();
// 初始化一个:签名校验的handler
$handlerSign = new HandlerSign();
// 初始化一个:访问权限校验的handler
$handlerAuthority = new HandlerAuthority();

// 构成对象链
$handlerAccessToken->setNext($handlerFrequent)
->setNext($handlerArguments)
->setNext($handlerSign)
->setNext($handlerAuthority);
// 启动网关
$handlerAccessToken->start($request);

} catch (\Exception $e) {
echo $e->getMessage();
}