責任鏈模式 -- 讓一個以上的物件有機會能夠處理某個請求
阿新 • • 發佈:2021-01-13
責任鏈模式 – 讓一個以上的物件有機會能夠處理某個請求
責任鏈的優點:
- 降低耦合度。它將請求的傳送者和接收者解耦;
- 簡化了物件。使得物件不需要知道鏈的結構;
- 增強給物件指派職責的靈活性。通過改變鏈內的成員或者調動它們的次序,允許動態地新增或者刪除責任;
- 增加新的請求處理類很方便。
責任鏈的缺點:
- 請求沒有明確的接收者,不能保證它一定會被處理,該請求可能一直到鏈的末端都得不到處理;
- 對於比較長的職責鏈,請求的處理可能涉及到多個處理物件,系統性能將受到一定影響,而且在進行程式碼除錯時不太方便,可能會造成迴圈呼叫
責任鏈2種形式:
純責任鏈模式和不純的責任鏈模式。
如果一個類要麼承擔責任處理請求要麼將請求踢給下一個皮球,則被稱為純責任鏈模式;如果一個類承擔了一部分責任,還將請求踢給下一個皮球,則被稱為不純的責任鏈模式。純的責任鏈模式的實際例子很難找到,一般看到的例子均是不純的責任鏈模式的實現。
使用場景舉例:
如點選廣告跳轉。
現有如下規則:點選廣告時先判斷是否滿足條件A,如果滿足A,則先嚐試用A方式跳轉,若A方式跳轉失敗,則再嘗試B方式。
程式碼舉例:
抽象基類: Jump.java
提供抽象方法, jump跳轉,各子類根據規則各自實現不同的邏輯。
public abstract class Jump {
private Jump mNext;
abstract boolean jump(Activity activity, MimoAdInfo adInfo);
public void setNext(Jump next) {
this.mNext = next;
}
protected void onSuccess(MimoAdInfo adInfo) {
}
protected void onFail(MimoAdInfo adInfo) {
}
public final boolean start(Activity activity, MimoAdInfo adInfo) {
boolean success = jump(activity, adInfo);
if (success) {
onSuccess(adInfo);
return true;
}
if (mNext != null) {
return mNext.start(activity, adInfo);
}
onFail(adInfo);
return false;
}
}
子類: DeepLinkJump.java
public class DeepLinkJump extends Jump{
@Override
boolean jump(Activity activity, MimoAdInfo adInfo) {
if (adInfo != null && !TextUtils.isEmpty(adInfo.mDeepLink)) {
try {
final Uri contentUrl = Uri.parse(adInfo.mDeepLink);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(contentUrl);
MimoAdManager.get().trackLauchStart(adInfo);
boolean success = IntentUtils.startActivity(activity, intent);
return success;
} catch (Exception e) {
return false;
}
}
return false;
}
@Override
protected void onSuccess(MimoAdInfo adInfo) {
MimoAdManager.get().trackLauchSuccess(adInfo);
}
@Override
protected void onFail(MimoAdInfo adInfo) {
MimoAdManager.get().trackLauchFail(adInfo);
}
}
子類:LandingPageJump.java
public class LandingPageJump extends Jump{
@Override
public boolean jump(Activity activity, MimoAdInfo adInfo) {
if (adInfo != null && !TextUtils.isEmpty(adInfo.mLandingPageUrl)) {
try {
if (adInfo.mLandingPageUrl.startsWith("http://") || adInfo.mLandingPageUrl.startsWith("https://")) {
LandingPageHelper.land(adInfo.mLandingPageUrl);
} else {
final Uri contentUrl = Uri.parse(adInfo.mLandingPageUrl);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(contentUrl);
return IntentUtils.startActivity(activity, intent);
}
} catch (Throwable throwable) {
return false;
}
return true;
}
return false;
}
}
子類:FloatCardDataJump.java
public class FloatCardDataJump extends Jump{
@Override
boolean jump(Activity activity, MimoAdInfo adInfo) {
if (adInfo != null && !TextUtils.isEmpty(adInfo.mFloatCardData)) {
try {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
final Uri contentUrl = Uri.parse(adInfo.mFloatCardData);
intent.setData(contentUrl);
boolean success = IntentUtils.startActivity(activity, intent);
return success;
} catch (Exception e) {
return false;
}
}
return false;
}
}
客戶端使用程式碼舉例:
/**
* 點選按鈕區域 先讀取floatcarddata,如果取不到該欄位,再讀取landingpageurl
* @param adInfo
*/
public static boolean jumpDownloadByFloatCardDataFirst(MimoAdInfo adInfo) {
if (adInfo != null && !TextUtils.isEmpty(adInfo.mFloatCardData)) {
FloatCardDataJump floatCardDataJump = new FloatCardDataJump();
floatCardDataJump.setNext(new LandingPageJump());
return floatCardDataJump.start(DkApp.get().getTopActivity(), adInfo);
} else {
LandingPageJump landingPageJump = new LandingPageJump();
return landingPageJump.jump(DkApp.get().getTopActivity(), adInfo);
}
}