Overview - 概述
將鏈中的每個節點看作是一個對象,每個對象處理的請求均不相同,每個節點內部自動維護下一個節點。請求從鏈的首端出發,沿着鏈的路徑,直到有節點處理這個請求。它屬於行爲型設計模式。
【簡言之】
允許你將請求沿着處理者鏈進行發送。 收到請求後, 每個處理者均可對請求進行處理, 或將其傳遞給鏈上的下個處理者。
【WIKI】
In object-oriented design, the chain-of-responsibility pattern is a design pattern consisting of a source of command objects and a series of processing objects.Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.
Structure - 結構
Applicability - 使用場景
- 需要使用不同的方式處理不同種類的請求,但是請求的類型和順序預先不知道。
這個模式讓幾個處理器連成鏈,一旦你收到請求,詢問每個處理器是否能夠處理它。每個處理器都有機會處理請求。
- 按順序執行多個處理者。
- 動態增加或者刪除處理器。
Pros and Cons - 優缺點
Code Demo - 代碼例子
@Data
@AllArgsConstructor
public class Member {
private String loginName;
private String loginPass;
private String roleName;
}
Deprecated code like the following :
public class MemberService {
public void login(String loginName, String loginPass) {
if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(loginPass)) {
System.out.println("用戶名或者密碼爲空");
return;
}
Member member = checkExists(loginName, loginPass);
if (member == null) {
System.out.println("用戶不存在");
return;
}
System.out.println("登陸成功");
if (!"管理員".equals(member.getRoleName())) {
System.out.println("您不是管理員,沒有操作權限 ");
return;
}
System.out.println("允許操作");
}
private Member checkExists(String loginName, String loginPass) {
return new Member(loginName, loginPass, "管理員");
}
}
Now we can use the pattern to improve below code, and let us try the following code.
Handler
public abstract class Handler {
@Setter
protected Handler next;
public Handler() {}
public abstract void handle(Member member);
}
ValidateHandler
public class ValidateHandler extends Handler {
@Override
public void handle(Member member) {
if (StringUtils.isEmpty(member.getLoginName()) || StringUtils.isEmpty(member.getLoginPass())) {
System.out.println("用戶名或者密碼爲空");
return;
}
if (super.next != null) {
super.next.handle(member);
}
}
}
LoginHandler
public class LoginHandler extends Handler {
@Override
public void handle(Member member) {
Member m = checkExists(member.getLoginName(), member.getLoginPass());
if (m == null) {
System.out.println("用戶不存在");
return;
}
System.out.println("登陸成功");
if (super.next != null) {
super.next.handle(member);
}
}
private Member checkExists(String loginName, String loginPass) {
return new Member(loginName, loginPass, "管理員");
}
}
AuthHandler
public class AuthHandler extends Handler {
@Override
public void handle(Member member) {
if (!"管理員".equals(member.getRoleName())) {
System.out.println("您不是管理員,沒有操作權限 ");
return;
}
System.out.println("允許操作");
if (super.next != null) {
super.next.handle(member);
}
}
}
Client
public class Client {
public static void main(String[] args) {
Member member = new Member("Tom", "123", "管理員");
Handler loginHandler = new LoginHandler();
Handler validateHandler = new ValidateHandler();
Handler authHandler = new AuthHandler();
loginHandler.setNext(validateHandler);
validateHandler.setNext(authHandler);
loginHandler.handle(member);
}
}
責任鏈模式與建造者模式 組合使用
Handler
public abstract class Handler {
@Setter
protected Handler next;
public Handler() {}
public abstract void handle(Member member);
public static class Builder {
private Handler head;
private Handler tail;
public Builder addHandler(Handler handler) {
if (handler == null) {return null;}
if (this.head == null) {
this.tail = this.head = handler;
return this;
}
this.tail.setNext(handler);
this.tail = handler;
return this;
}
public Handler build() {
return this.head;
}
}
}
Client
public class Client {
public static void main(String[] args) {
Member member = new Member("Tom", "123", "管理員");
Handler loginHandler = new LoginHandler();
Handler validateHandler = new ValidateHandler();
Handler authHandler = new AuthHandler();
Handler.Builder builder = new Handler.Builder();
builder.addHandler(loginHandler)
.addHandler(validateHandler)
.addHandler(authHandler)
.build()
.handle(member);
}
}