Skip to content

Commit e16ac84

Browse files
committed
add chain responsibility and command pattern
1 parent 6576990 commit e16ac84

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+926
-0
lines changed

chain-responsibility/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# 简介
2+
责任链模式(Chain of Responsibility Pattern)是一种行为型设计模式,也叫职责链模式、命令链模式。这种模式为请求创建了一个接收者对象的链,允许你将请求沿着处理者链进行发送,每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
3+
4+
当程序需要使用不同方式来处理多种类请求,且请求类型和顺序不可知,或者当必须按顺序执行多个处理时,可以使用责任链模式。或者如果所需处理及其顺序必须在运行时进行改变,也可以使用该模式。
5+
6+
# 作用
7+
1. 避免请求发送者与接收者耦合在一起,客户只需要将请求发送到链上,而无须关心请求的处理细节和请求的传递。
8+
2. 通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
9+
10+
# 实现步骤
11+
1. 创建一个抽象处理器类,用来供处理器继承。
12+
2. 抽象处理器类可将各子类按任意组织为链式,以便调用。
13+
3. 创建多个互不干涉的处理器,实现抽象类的next方法,以便不断执行链式检查。
14+
15+
# UML
16+
<img src="../docs/uml/chain-responsibility.png">
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package src;
2+
3+
// 抽象处理类,所有处理变成链式,可以互动干涉,动态组合
4+
public abstract class AbstractHandler {
5+
// 形成职责链
6+
private AbstractHandler next;
7+
8+
// 创建调用链,传入多个handler,按顺序形成链,返回第一个handler
9+
public static AbstractHandler link(AbstractHandler first, AbstractHandler... chain) {
10+
AbstractHandler head = first;
11+
for (AbstractHandler handler : chain) {
12+
head.next = handler;
13+
head = handler;
14+
}
15+
return first;
16+
}
17+
18+
// 子类需要实现的检查方法
19+
public abstract boolean check(int uid);
20+
21+
// 继续下一个检查
22+
protected boolean checkNext(int uid) {
23+
if (next == null) {
24+
return true;
25+
}
26+
return next.check(uid);
27+
}
28+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package src;
2+
3+
// 权限检查类
4+
public class AuthHandler extends AbstractHandler {
5+
// 如果检查不通过则返回失败,否则继续下一个检查
6+
public boolean check(int uid) {
7+
System.out.println(this.getClass().getName() + "::check() [uid = " + uid + "]");
8+
if (uid % 2 == 0) {
9+
return false;
10+
}
11+
return checkNext(uid);
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package src;
2+
3+
// 请求是否安全合法检查
4+
public class RequestHandler extends AbstractHandler {
5+
// 如果检查不通过则返回失败,否则继续下一个检查
6+
public boolean check(int uid) {
7+
System.out.println(this.getClass().getName() + "::check() [uid = " + uid + "]");
8+
if (uid % 1 != 0) {
9+
return false;
10+
}
11+
return checkNext(uid);
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package src;
2+
3+
// 用户基本信息检查类
4+
public class UserHandler extends AbstractHandler {
5+
// 如果检查不通过则返回失败,否则继续下一个检查
6+
public boolean check(int uid) {
7+
System.out.println(this.getClass().getName() + "::check() [uid = " + uid + "]");
8+
if (uid % 3 == 0) {
9+
return false;
10+
}
11+
return checkNext(uid);
12+
}
13+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package test;
2+
3+
import src.*;
4+
5+
public class Test {
6+
7+
public static void start() {
8+
9+
// 责任链模式核心是打造一个调用处理链,每个处理链都实现抽象类的next方法,从而可以任意组织各种检查链。
10+
11+
// 可以任意组织职责链,先后顺序根据需要来
12+
AbstractHandler handler1 = AbstractHandler.link(
13+
new RequestHandler(),
14+
new UserHandler(),
15+
new AuthHandler());
16+
17+
System.out.println("handler1.check(1001)开始");
18+
handler1.check(1001);
19+
System.out.println("handler1.check(1002)开始");
20+
handler1.check(1002);
21+
22+
// 可以任意组织职责链,先后顺序根据需要来
23+
AbstractHandler handler2 = AbstractHandler.link(
24+
new AuthHandler(),
25+
new RequestHandler(),
26+
new UserHandler());
27+
28+
System.out.println("handler2.check(1001)开始");
29+
handler2.check(1001);
30+
System.out.println("handler2.check(1002)开始");
31+
handler2.check(1002);
32+
33+
}
34+
35+
public static void main(String[] args) {
36+
System.out.println("test start:");
37+
start();
38+
}
39+
}
40+
/**
41+
* 测试
42+
* jarry@jarrys-MacBook-Pro java % javac test/Test.java
43+
* jarry@jarrys-MacBook-Pro java % java test/Test
44+
* test start:
45+
* handler1.check(1001)开始
46+
* src.RequestHandler::check() [uid = 1001]
47+
* src.UserHandler::check() [uid = 1001]
48+
* src.AuthHandler::check() [uid = 1001]
49+
* handler1.check(1002)开始
50+
* src.RequestHandler::check() [uid = 1002]
51+
* src.UserHandler::check() [uid = 1002]
52+
* handler2.check(1001)开始
53+
* src.AuthHandler::check() [uid = 1001]
54+
* src.RequestHandler::check() [uid = 1001]
55+
* src.UserHandler::check() [uid = 1001]
56+
* handler2.check(1002)开始
57+
* src.AuthHandler::check() [uid = 1002]
58+
*/

chain-responsibility/js/package.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"name": "esm-project",
3+
"version": "1.0.0",
4+
"main": "test/test.js",
5+
"scripts": {
6+
"test": "node test/test.js"
7+
},
8+
"type": "module"
9+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// 抽象处理类,所有处理变成链式,可以互动干涉,动态组合
2+
export class AbstractHandler {
3+
constructor() {
4+
this.next = undefined
5+
}
6+
7+
// 创建调用链,传入多个handler,按顺序形成链,返回第一个handler
8+
static link(first, ...chain) {
9+
let head = first
10+
for (const handler of chain) {
11+
head.next = handler
12+
head = handler
13+
}
14+
15+
return first
16+
}
17+
18+
// 子类需要实现的检查方法
19+
check(uid) {}
20+
21+
// 继续下一个检查
22+
checkNext(uid) {
23+
if (!this.next) {
24+
return true
25+
}
26+
return this.next.check(uid)
27+
}
28+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { AbstractHandler } from './AbstractHandler.js'
2+
3+
// 权限检查类
4+
export class AuthHandler extends AbstractHandler {
5+
// 如果检查不通过则返回失败,否则继续下一个检查
6+
check(uid) {
7+
console.log(this.constructor.name + '::check() [uid = ' + uid + ']')
8+
if (uid % 2 == 0) {
9+
return false
10+
}
11+
return this.checkNext(uid)
12+
}
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { AbstractHandler } from './AbstractHandler.js'
2+
3+
// 请求是否安全合法检查
4+
export class RequestHandler extends AbstractHandler {
5+
// 如果检查不通过则返回失败,否则继续下一个检查
6+
check(uid) {
7+
console.log(this.constructor.name + '::check() [uid = ' + uid + ']')
8+
if (uid % 1 !== 0) {
9+
return false
10+
}
11+
return this.checkNext(uid)
12+
}
13+
}

0 commit comments

Comments
 (0)