09 Android常见设计模式:责任链模式

前言

责任链模式(Iterator Pattern),是行为型设计模式之一。什么是“链”?我们将多个节点首尾相连所构成的模型称为链,比如生活中常见的锁链,就是由一个个圆角长方形的铁环串起来的结构。对于链式结构,每个节点都可以被拆开再连接,因此,链式结构也具有很好的灵活性。将这样一种结构应用于编程领域,将每一个节点看作是一个对象,每一个对象拥有不同的处理逻辑,将一个请求从链式的首端发出,沿着链的路径依次传递给每一个节点对象,直至有对象处理这个请求为止,我们将这样的一种模式称为责任链模式。在Android中责任链的实现莫过于对事件的分发处理。

定义

使多个对象都有机会处理请求,从而避免了请求的发送者和接收者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有对象处理它为止。

使用场景

  1. 多个对象可以处理同一请求,但具体由哪个对象处理则在运行时动态决定。
  2. 在请求处理者不明确的情况下向多个对象中的一个提交一个请求。

简单案例

小民某天接到通知说需要出差去外地进修学习新技术,小民听到这消息心中一喜,于是收拾完背包后踏上了去外地进修的旅途。去外地学习一趟花费了近5万元,于是小民上班后的第一天就向组长申请报销费用,组长一看是笔不小的数目,他没有权限审批,于是组长就拿着票据去找部门主管,主管一看要报这么多钱,自己权限内只能批五千以下的费用,这完全超出了自己的权限范围,于是主管又跑去找经理,经理一看二话不说直接拿着票据奔向了老板的办公室,因为他也只能批一万以下的费用。类似的情况对上班族来说肯定并不少见,上面的这个情景其实就是一个责任链的小例子,每一个人,准确地说是每一类人代表这条链上的一个节点,小民是请求的发起者,而老板则是处于链条顶端的类,小民从链的底端开始发出一个申请报账的请求,首先由组长处理该请求,组长比对后发现自己权限不够于是将该请求转发给位于链中下一个节点的主管,主管比对后也发现自己权限不够又将该请求转发给经理,而经理也基于同样的原因将请求转发给老板,这样层层转达直至请求被处理,从中大家可以看到一个显而易见的事,就是至始至终小民只与组长产生了关联,后面具体由谁处理的票据,小民并不关心,唯一在乎的是报账的结果,责任链模式在这里很好地将请求的发起者与处理者解耦。

  1. 声明一个抽象的领导类。
public abstract class Leader {

    //上一级领导处理者
    public Leader nextHandler;

    /**
     * 处理报账请求
     *
     * @param money 能批复的报账额度
     */
    public final void handleRequest(int money) {
        if (money <= limit()) {
            handle(money);
        } else {
            if (null != nextHandler)
                nextHandler.handleRequest(money);
        }
    }

    /**
     * 自身能批复的额度权限
     * * @return 额度
     */
    public abstract int limit();

    /**
     * 处理报账行为
     *
     * @param money 具体金额
     */
    public abstract void handle(int money);
}

在这个抽象的领导类中只做了两件事,一是定义了两个抽象接口方法来确定一个领导者应有的行为和属性,二是声明了一个处理报账请求的方法来确定当前领导是否有能力处理报账请求,如果没有这权限,则将该请求转发给上级领导处理。接下来则是各个领导类的实现。

public class GroupLeader extends Leader{

    @Override
    public int limit() {
        return 1000;
    }

    @Override
    public void handle(int money) {
        System.out.println("组长批复报销" + money + "元");
    }
}
public class Director extends Leader{

    @Override
    public int limit() {
        return 5000;
    }

    @Override
    public void handle(int money) {
        System.out.println("主管批复报销" + money + "元");
    }
}
public class Manager extends Leader{

    @Override
    public int limit() {
        return 10000;
    }

    @Override
    public void handle(int money) {
        System.out.println("经理批复报销" + money + "元");
    }
}
public class Boss extends Leader {

    @Override
    public int limit() {
        return Integer.MAX_VALUE;
    }

    @Override
    public void handle(int money) {
        System.out.println("老板批复报销" + money + "元");
    }
}

最后,小明从组长开始发起请求申请报账。

public static void main(String[] args) {
     // 构造各个领导对象
     GroupLeader groupLeader = new GroupLeader();
     Director director = new Director();
     Manager manager = new Manager();  
     Boss boss = new Boss();   

     // 设置上一级领导处理者对象  
     groupLeader.nextHandler = director;
     director.nextHandler = manager;  
     manager.nextHandler = boss; 

      // 发起报账申请
      groupLeader.handleRequest(50000);  
 }

总结

世界不是完美的,所以不会有完美的事物存在。就像所有的设计模式一样,有优点也有缺点,但总体来说优点必定大于缺点或者说缺点相对于优点来说更可控。责任链模式也一样,优点显而易见,可以对请求者和处理者关系解耦,提高代码的灵活性。责任链模式的最大缺点是对链中请求处理者的遍历,如果处理者太多那么遍历必定会影响性能,特别是在一些递归调用中,要慎重。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容