責任鏈模式
是一種對象的行爲模式,在其中,很多對象由每一個對象對其下家的引用而連接起來,形成的一條鏈。客戶端請求在這個鏈上進行傳遞,直到鏈上的某一個對象決定處理此請求。
角色
1。抽象處理者角色(Handler):定義出一個處理請求的接口,如有需要,可設定和返回下家的引用。--java抽象或java接口
2。具體處理者角色。
設計原則
1.開-閉 原則 --對擴展開放,對修改關閉
2.單一職責原則--處理功能的單
注意:在每一個類的功能單一,也方便定位問題的所在,但是需要注意的一點是,如果責任鏈中的處理借點過多,也會造成調試的不方便,所以,使用責任鏈的時候,要注意出現節點過多的情況出現。
使用場合
1.多個對象處理同一個請求,具體由哪一個來處理還不確定,只有在運行時才能確定那個對象處理的情況
2.消息具有多個接收者,而接收對象又不是很明確的情況
3.同一個消息的多個處理對象可能會動態的增加或者減少。即處理這個消息的中間步驟會增加或減少
擴展
1.java中 java.lang.ClassLoader 爲典型的責任鏈模式
java實現採用“雙親委派的加載鏈”,在classLoader中存在一個指向父類的指針parent,在構造方法中傳入父類對象引用。
vm啓動時,會啓動jre/rt.jar裏的類加載器:bootstrap classloader,用來加載java核心api;然後啓動擴展類加載器ExtClassLoader加載擴展類,並加載用戶程序加載器AppClassLoader,並指定ExtClassLoader爲他的父類;
當類被加載時,會先檢查在內存中是否已經被加載,如果是,則不再加載,如果沒有,再由AppClassLoader來加載,先從jar包裏找,沒有再從classpath裏找;
2.相關設計模式
2.1外觀模式,在責任鏈中,需要用到外觀模式(將子模塊中需要給用戶調用的類,抽出來,建立一個更高一層的類,提供用戶調用),使用戶只需與外觀打交道,不需要去管內部是如何實現的
2.2組合模式,責任鏈模式也是一種樹形結構,只不過是一條主幹,而沒有分支而已
2.3命令模式
2.4觀察者模式
demo
學生請假
1.定義責任鏈接口類 IHandler
//責任鏈定義方法
public interface IHandler {
public void handleRequest(AbstractStuistudent);
public void setHander(IHandler handler);
}
2.抽象處理者角色 AbstractHandler
public abstract class AbstractHandler implements IHandler{
protected IHandler hander=null;
protected int state = -1;
//此處重點,傳遞下一步處理的引用
public AbstractHandler(IHandler hander) {
this.hander = hander;
}
@Override
public void setHander(IHandler handler) {
this.hander = handler;
}
}
3.具體處理者班長
public class SquadLeaderHander extends AbstractHandler{
public SquadLeaderHander(IHandler handler) {
super(handler);//傳遞下一步處理的引用
this.state = 0;
}
@Override
public void handleRequest(AbstractStu istudent){
System.out.print("班長-->");
// TODO Auto-generated method stub
if (this.state == istudent.getState())
System.out.print(istudent.getRequestMessage()+" 班長批閱,請假成功");
else {
if(this.hander!=null)
this.hander.handleRequest(istudent);
else
System.out.print("未通過班長同意,請假失敗");
}}}
4.具體處理者老師
public class TeacherHander extends AbstractHandler{
public TeacherHander(IHandler hander) {
super(hander);
this.state = 1;}
@Override
public void handleRequest(AbstractStu istudent){
System.out.print("老師-->");
if (this.state == istudent.getState())
System.out.print(istudent.getRequestMessage()+ " 老師批閱,請假成功");
else {
if (this.hander != null)
this.hander.handleRequest(istudent);
else
System.out.print("未通過老師同意,請假失敗");
}}}
5.具體處理者校長
public class SchoolMasterHander extends AbstractHandler{
public SchoolMasterHander(IHandler hander) {
super(hander);
this.state = 2;
}
@Override
public void handleRequest(AbstractStu istudent){
System.out.print("校長-->");
// TODO Auto-generated method stub
if (this.state == istudent.getState())
System.out.print(istudent.getRequestMessage()+ " 校長批閱,請假成功");
else {
if (this.hander != null)
this.hander.handleRequest(istudent);
else
System.out.print("未通過校長同意,請假失敗");}}}
6. 學生接口
public interface Istudent {
public int getState();
public String getRequestMessage();
}
7.抽象
public abstract class AbstractStu implements Istudent{
protected int state = -1;
protected String msg;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
8.具體實現
public class Student extends AbstractStu{
public Student(String msg) {
this.msg = msg;
}
public Student(int state, String msg) {
this.state = state;
this.msg = msg;
}
@Override
public int getState() {
// TODO Auto-generated method stub
return this.state;
}
@Override
public String getRequestMessage() {
// TODO Auto-generated method stub
return this.msg;
}}
9.創建外觀類,使用戶忽略細節,只與外觀類打交道(外觀模式)
Facade
public class Facade {
private IHandler iSquad;
private IHandler teacher;
private IHandler schoolMaster;
public Facade() {
schoolMaster = new SchoolMasterHander(null);
teacher = new TeacherHander(schoolMaster);
iSquad = new SquadLeaderHander(teacher);
}
// 請假
public void leave(AbstractStu studnt) {
// 客戶端自己定義級別
studnt.setState(statejudge(studnt));
// 開始走責任鏈,首先從班長開始
iSquad.handleRequest(studnt);
}
// 根據具體內容,系統判定級別,此處還可以設置一條針對與請假理由的初次篩選的責任鏈
private int statejudge(AbstractStu stu) {
int state = -1;
if (stu.getMsg() == null ||stu.getMsg().length() == 0) {
} else {
if (stu.getRequestMessage().contains("有事情")) {
state = 0;
}
if (stu.getRequestMessage().contains("生病")
|| stu.getRequestMessage().contains("不舒服")) {
state = 1;
}
if (stu.getRequestMessage().contains("住院")) {
state = 2;
} else
state = stu.getState();
}
return state;}}
10.測試
Facade facade = new Facade();
AbstractStu student = new Student("身體不舒服,去醫院看病.可能需要住院");
facade.leave(student);