责任链模式 – 让一个以上的对象有机会能够处理某个请求
责任链的优点:
- 降低耦合度。它将请求的发送者和接收者解耦;
- 简化了对象。使得对象不需要知道链的结构;
- 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任;
- 增加新的请求处理类很方便。
责任链的缺点:
- 请求没有明确的接收者,不能保证它一定会被处理,该请求可能一直到链的末端都得不到处理;
- 对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用
责任链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);
}
}