編輯:關於Android編程
這篇博客我們來介紹一下責任鏈模式(Chain-of-responsibility Pattern),責任聯模式又稱為職責鏈模式,是行為型設計模式之一。顧名思義,責任鏈模式中存在一個鏈式結構,多個節點首尾相連,每個節點都可以被拆開再連接,因此,鏈式結構具有很好的靈活性。將這樣一種結構應用於編程領域,將每一個節點看作是一個對象,每一個對象擁有不同的處理邏輯,將一個請求從鏈式的首段發出,沿著鏈的路徑依次傳遞給每一個節點對象,直至有對象處理這個請求為止,這就是責任鏈或者職責鏈的通俗定義。
使多個對象都有機會處理請求,從而避免了請求的發送者和接收者之間的耦合關系,將這些對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有對象處理它為止。
責任鏈模式的使用場景:
責任鏈模式的 uml 圖如下所示:
責任鏈模式有兩大角色:
public abstract class AbstractHandler { protected AbstractHandler nextHandler; public final void handleRequest(AbstractRequest request) { if (getHandlerLevel() == request.getLevel()) { handle(request); } else { if (nextHandler != null) { nextHandler.handleRequest(request); } else { System.out.print("there is no handler that can handle this request"); } } } protected abstract int getHandlerLevel(); protected abstract void handle(AbstractRequest request); }
ConcreteHandler1.class
public class ConcreteHandler1 extends AbstractHandler{ @Override protected int getHandlerLevel() { return 1; } @Override protected void handle(AbstractRequest request) { System.out.print("ConcreteHandler1 handle this request : " + request.getContent() + "\n"); } }
ConcreteHandler2.class
public class ConcreteHandler2 extends AbstractHandler{ @Override protected int getHandlerLevel() { return 2; } @Override protected void handle(AbstractRequest request) { System.out.print("ConcreteHandler2 handle this request : " + request.getContent() + "\n"); } }
然後是請求角色:
AbstractRequest.class
public abstract class AbstractRequest { private Object object; public AbstractRequest(Object object) { this.object = object; } public Object getContent() { return object; } public abstract int getLevel(); }
ConcreteRequest1.class
public class ConcreteRequest1 extends AbstractRequest{ public ConcreteRequest1(Object object) { super(object); } @Override public int getLevel() { return 1; } }
ConcreteRequest2.class
public class ConcreteRequest2 extends AbstractRequest{ public ConcreteRequest2(Object object) { super(object); } @Override public int getLevel() { return 2; } }
最後客戶端測試代碼:
public class Client { public static void main(String[] args) { AbstractHandler handler1 = new ConcreteHandler1(); AbstractHandler handler2 = new ConcreteHandler2(); handler1.nextHandler = handler2; AbstractRequest request1 = new ConcreteRequest1("request1"); AbstractRequest request2 = new ConcreteRequest2("request2"); handler1.handleRequest(request1); handler1.handleRequest(request2); } }
結果如下:
其實責任鏈模式在實際項目過程中遇到的非常多,Android 和 Java 源碼也一樣,舉幾個簡單的例子:
ViewGroup 和 View 中 touch 事件的分發,子 View 的 onTouchEvent 返回 true 代碼消費該事件並不再傳遞,false 代表不消費並且傳遞到父 ViewGroup 去處理,這些樹形結構的子 View 就是責任鏈上一個個處理對象;OrderedBroadcast,廣播的每一個接收者按照優先級依次接受消息,如果處理完成之後可以調用 abortBroadcast 終止廣播,不是自己處理的就可以傳遞給下一個處理者;try-catch語句,每一個 catch 根據 Exception 類型進行匹配,形成一個責任鏈,如果有一個 catch 語句與該 Exception 符合,這個 Exception 就交由給它進行處理,之後所有 catch 語句都不會再次執行。
public abstract class PurchasePower { protected static final double BASE = 500; protected PurchasePower successor; abstract protected double getAllowable(); abstract protected String getRole(); public void setSuccessor(PurchasePower successor) { this.successor = successor; } public void processRequest(PurchaseRequest request){ if (request.getAmount() < this.getAllowable()) { System.out.println(this.getRole() + " will approve $" + request.getAmount()); } else if (successor != null) { successor.processRequest(request); } } }
public class ManagerPPower extends PurchasePower { protected int getAllowable(){ return BASE*10; } protected String getRole(){ return "Manager"; } } public class DirectorPPower extends PurchasePower { protected int getAllowable(){ return BASE*20; } protected String getRole(){ return "Director"; } } public class VicePresidentPPower extends PurchasePower { protected int getAllowable(){ return BASE*40; } protected String getRole(){ return "Vice President"; } } public class PresidentPPower extends PurchasePower { protected int getAllowable(){ return BASE*60; } protected String getRole(){ return "President"; } }
審批類
public class PurchaseRequest { private double amount; private String purpose; public PurchaseRequest(double amount, String purpose) { this.amount = amount; this.purpose = purpose; } public double getAmount() { return amount; } public void setAmount(double amt) { amount = amt; } public String getPurpose() { return purpose; } public void setPurpose(String reason) { purpose = reason; } }
最後是客戶端的測試代碼:
public class CheckAuthority { public static void main(String[] args) { ManagerPPower manager = new ManagerPPower(); DirectorPPower director = new DirectorPPower(); VicePresidentPPower vp = new VicePresidentPPower(); PresidentPPower president = new PresidentPPower(); manager.setSuccessor(director); director.setSuccessor(vp); vp.setSuccessor(president); // Press Ctrl+C to end. try { while (true) { System.out.println("Enter the amount to check who should approve your expenditure."); System.out.print(">"); double d = Double.parseDouble(new BufferedReader(new InputStreamReader(System.in)).readLine()); manager.processRequest(new PurchaseRequest(d, "General")); } } catch(Exception e) { System.exit(1); } } }
代碼簡潔明了,都應該能看懂。
責任鏈模式的優點顯而易見,可以對請求者和處理者關系解耦,提高代碼的靈活性,通過改變鏈內的成員或調動他們的次序,允許你動態地新增或者刪除職責;但是責任鏈模式最大的缺點在於對鏈中請求處理者的遍歷,如果處理者太多那麼必定會影響性能,特別是在一些遞歸調用中,而且不容易觀察運行時的特征,有礙於除錯。
很多資料中會介紹純和不純的責任鏈模式,在標准的責任鏈模式中,責任鏈上的一個節點只允許有兩個行為:處理或者推給下個節點處理,而不允許處理完之後又推給下個節點,前者被很多資料稱為純的責任鏈模式,而後者被稱為不純的責任鏈模式。其實在實際的系統裡,純的責任鏈很難找到。如果堅持責任鏈不純便不是責任鏈模式,那麼責任鏈模式便不會有太大意義了。
https://github.com/zhaozepeng/Design-Patterns/tree/master/ChainOfResponsibilityPattern
Android定義了一種權限方案來保護設備上的資源和功能。例如,在默認情況下,應用程序無法訪問聯系人列表、撥打電話等。下面就以撥打電話為例介紹一下系統對權限的要求。一般在
ActionBar & Toolbar設置ActionView我們可以在菜單中設置ActionView,比如搜索,他是一個帶圖標和輸入框的控件,他分別有兩種不同的
1G - 5G的介紹 Android的操作系統的介紹 Android版本 Android系統的架構 兩種虛擬機的不同 ART模式 模擬器的簡介 SDK目錄 Andro
Android基礎入門教程——8.4.3 Android動畫合集之屬性動畫-初見標簽(空格分隔): Android基礎入門教程本節引言: 本節給帶