很是抱歉,本系列博客長達半年沒更新了,今日偶得靈感,更新一波《設計模式Android篇:責任鏈模式》。點擊此處查看《Design Patterns in Android》系列其餘文章。java
本文原創做者MichaelX。設計模式
CSDN博客:http://blog.csdn.net/xiong_it緩存
掘金主頁:https://juejin.im/user/56efe6461ea493005565dafdbash
知乎專欄:https://zhuanlan.zhihu.com/c_144117654網絡
我的博客:http://blog.michaelx.techui
轉載請註明出處。this
職責鏈(Chain-of-responsibility pattern):它是一種對象的行爲模式。在責任鏈模式裏,不少對象由每個對象對其下家的引用而鏈接起來造成一條鏈。請求在這個鏈上傳遞,直到鏈上的某一個對象決定處理此請求。發出這個請求的客戶端並不知道鏈上的哪個對象最終處理這個請求,這使得系統能夠在不影響客戶端的狀況下動態地從新組織和分配責任。spa
這裏舉個栗子:老王在中介所要買個二手房,他提出價格太高,但願獲得更多的優惠,好比88折,中介經紀人小明收到請求。如下是處理流程。.net
Client發起購房請求線程
public class Client {
public static void main(String[] args) {
HouseBuyer laowang = new HouseBuyer("老王");
laowang.buyHouse("88折賣不賣?");
}
}
public class HouseBuyer {
public void buyHouse(int accountOff) {
AbsAgency xiaoming = new Staff("底層員工小明");
xiaoming.handle(accountOff);
}
}
複製代碼
抽象處理者Handler
public abstract class AbsAgency {
protected AbsAgency mAgency;
public void setNextHandler(AbsAgency agency) {
this.mAgency = agency;
}
// 處理折扣
public abstract void handle(int accountOff);
public AbsAgency geNextHandler() {
return mAgency;
}
}
複製代碼
具體處理者:處理購房請求
public class Staff extends AbsAgency {
public abstract void handle(int accountOff) {
// 若是折扣低於80折,不出售;
// 若是90折以上,一線員工自行處理;
// 低於90折,須要彙報經理處理
if (accountOff <= 80) {
System.out.println("價格過低,要吃土咯。。。");
} else if (accountOff > 90 && accountOff <= 100) {
System.out.println("價格合適,賣給你了。");
} else {
setNextHandler(new Manager("上級經理"));
getNextHandler().handle(accountOff);
}
}
}
public class Manager extends AbsAgency {
public abstract void handle(int accountOff) {
// 若是折扣低於80折,不出售;
// 根據人品決定是否接受購房請求
if (accountOff <= 80) {
System.out.println("價格過低,要吃土咯。。。");
} else {
System.out.println("老王人品還行,成交。");
}
}
複製代碼
最終老王的購房請求在經理這個級別獲得了處理,可是老王纔不關心誰解決的,只要能低價買到這個房子就好了。
責任鏈模式思想在Android源碼中的體現莫過於:觸摸事件的處理和分發了。每當用戶接觸屏幕時,Android都會將其打包成一個MotionEvent對象從ViewTree自頂而下的分發處理。 代碼過多,這裏只用一張圖表示其思路:
其方向爲:Activity--->ViewGroup--->View
具體源碼可參考郭神的
《Android事件分發機制徹底解析,帶你從源碼的角度完全理解(上)》,閱讀源碼,咱們能夠發現dispatchTouchEvent有點相似上面責任鏈實例代碼中的handle()方法,本身能處理就處理,處理不了就向下一級分發處理。
舉個例子,咱們的圖片須要設計三級緩存,那麼它是怎麼取緩存的呢?
AbsCacheManager bmpCache = new MemoryCache();
Bitmap bmp = bmpCache.getCache(cacheKey);
複製代碼
先定義一個緩存抽象類
public abstract class AbsCacheManager {
protected AbsCacheManager mCache;
// 獲取Bitmap
public abstract Bitmap getCache(String cacheKey);
public void setNextHandler(AbsCacheManager manager) {
mCache = manager;
}
public AbsCacheManager getNextHandler() {
return mCache;
}
}
複製代碼
下面是具體實施者:內存緩存,磁盤緩存,網絡獲取
public class MemoryCache extends AbsCacheManager {
public Bitmap getCache(String cacheKey) {
Bitmap bmp = getCacheFromMemory(cacheKey);
// 若是內存緩存爲空,則將請求傳遞給下一位:磁盤緩存來處理
if (bmp == null) {
setNextHandler(new DiskCache());
bmp = getNextHandler().getCache(cacheKey);
}
return bmp;
}
}
public class DiskCache extends AbsCacheManager {
public Bitmap getCache(String cacheKey) {
Bitmap bmp = getCacheFromDisk(cacheKey);
// 若是磁盤緩存爲空,則將請求傳遞給下一位:網絡圖片下載來處理
if (bmp == null) {
setNextHandler(new NetworkFetchManager());
bmp = getNextHandler().getCache(cacheKey);
}
return bmp;
}
}
public class NetworkFetchManager extends AbsCacheManager {
public Bitmap getCache(String cacheKey) {
Bitmap bmp = getCacheFromNetWork(cacheKey);
return bmp;
}
}
複製代碼
一條責任鏈躍然紙上:內存—>磁盤->網絡。
固然,以上沒有考慮線程切換問題,實際操做是須要考慮耗時操做在子線程執行的。
其實責任鏈模式就是在某種場景下:有一個請求須要處理,可是最終處理者又不肯定的時候採用的一種模式。 可是其處理者對於客戶端是透明的,無需知道誰將處理這個請求,只須要拋出請求,拿到結果便可。