android设计模式二十三式(十七)——责任链模式(Chain of Responsibility)

责任链模式

阅读过handler源码的同学,可能还有印象,handler的message存在队列中是以链式结构存在的,所以,这里,我们的责任链模式,核心就是一个链式的结构。

当一个对象持有对下一个对象的引用,这样就会形成一条链,请求在这条链上传递,直到某一对象决定处理该请求。但是发出者并不清楚到底最终哪个对象会处理该请求,所以,责任链模式可以实现,在隐瞒客户端的情况下,对系统进行动态的调整。

我们还是举一个现实的例子:现在孩子上学,要有学籍才行,当我们先去找学校,学校说要教育局办学籍,去到教育局,说要派出所的户口本,去到派出所,说要医院的出生证明,于是去到医院拿到了出生证明,再回到派出所办理户口本,再去教育局办理学籍。这样就是一个从上至下再回来的一个完整的处理。

我们来看一下代码

抽象一个类,所有组织的父类,在父类方法operation中对事件进行处理,子类正常情况下不应复写此类。

/**
 * @author: hx
 * @Time: 2019/5/22
 * @Description: Org
 */
public abstract class Org {
    private String name;
    private Org next;

    public Org(String name) {
        this.name = name;
    }

    public Org setNext(Org next) {
        this.next = next;
        return next;
    }

    /**
     * 执行操作
     */
    public boolean operation(Parents parents){
        if (solve(parents)){
            System.out.println("---"+name + "能处理此问题");
            return true;
        }else if (next != null){
            System.out.println("---"+name + "不能处理此问题,下一级处理");
            if (next.operation(parents)) {
                System.out.println("---"+name + "的下一级处理成功,本级再次处理");
                solve(parents);
                return true;
            }else {
                System.out.println("---"+name + "的下一级处理失败");
                failed(parents);
            }
            return false;
        }else {
            System.out.println("---"+name+ "已经是最后一级");
            failed(parents);
            return false;
        }
    }

    /**
     * 处理操作
     * @param parents
     */
    protected abstract boolean solve(Parents parents);

    /**
     *
     * @param parents
     * @return
     */
    protected abstract void failed(Parents parents);


}

再写一个有个要上学的孩子的父母类,包含出生日期,出生证明,户口本,学籍这些关键的字段。

/**
 * @author: hx
 * @Time: 2019/5/22
 * @Description: Parents
 */
public class Parents {
    private String birthCertificate;
    private String householdRegister;
    private String studentProof;
    private String birthday;

    public String getBirthCertificate() {
        return birthCertificate;
    }

    public void setBirthCertificate(String birthCertificate) {
        this.birthCertificate = birthCertificate;
    }

    public String getHouseholdRegister() {
        return householdRegister;
    }

    public void setHouseholdRegister(String householdRegister) {
        this.householdRegister = householdRegister;
    }

    public String getStudentProof() {
        return studentProof;
    }

    public void setStudentProof(String studentProof) {
        this.studentProof = studentProof;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }
}

下面就是集成org组织的子类实现了,学校,教育局,派出所,医院。

/**
 * @author: hx
 * @Time: 2019/5/22
 * @Description: School
 */
public class School extends Org {

    public School() {
        this("学校");
    }

    public School(String name) {
        super(name);
    }

    @Override
    protected boolean solve(Parents parents) {
        if (parents.getStudentProof()!= null){
            System.out.println("有学籍证明,可以入学");
            return true;
        }else{
            System.out.println("没有学籍证明,需要去教育局办理");
            return false;
        }
    }

    @Override
    protected void failed(Parents parents) {
        System.out.println("失败-没有学籍证明,教育局不给办理");
    }
}

/**
 * @author: hx
 * @Time: 2019/5/22
 * @Description: EducationBureau
 */
public class EducationBureau extends Org {

    public EducationBureau() {
        this("教育局");
    }

    public EducationBureau(String name) {
        super(name);
    }

    @Override
    protected boolean solve(Parents parents) {
        if (parents.getHouseholdRegister() != null){
            parents.setStudentProof("学籍");
            System.out.println("有户口本,可以办理学籍");
            return true;
        }else {
            System.out.println("没有户口本,需派出所办理");
            return false;
        }
    }

    @Override
    protected void failed(Parents parents) {
        System.out.println("失败-没有户口本,派出所办不给办理");
    }
}

/**
 * @author: hx
 * @Time: 2019/5/22
 * @Description: PoliceStation
 */
public class PoliceStation extends Org {

    public PoliceStation() {
        this("派出所");
    }

    public PoliceStation(String name) {
        super(name);
    }

    @Override
    protected boolean solve(Parents parents) {
        if (parents.getBirthCertificate() != null){
            parents.setHouseholdRegister("户口本");
            System.out.println("有出生证明,办理户口本");
            return true;
        }else {
            System.out.println("没有出生证明,需医院开证明");
            return false;
        }
    }

    @Override
    protected void failed(Parents parents) {
        System.out.println("失败-没有出生证明,医院不给开证明");
    }
}

/**
 * @author: hx
 * @Time: 2019/5/22
 * @Description: Hospital
 */
public class Hospital extends Org {

    public Hospital() {
        this("医院");
    }

    public Hospital(String name) {
        super(name);
    }

    @Override
    protected boolean solve(Parents parents) {
        if (parents.getBirthday() != null){
            parents.setBirthCertificate("出生证明");
            System.out.println("没有出生证明,开一个出生证明");
            return true;
        }else{
            System.out.println("不知道出生日期,不给开出生证明");
            return false;
        }
    }

    @Override
    protected void failed(Parents parents) {
        System.out.println("失败-医院不给开出生证明");
    }
}

先来一个有出生日期的父母

public static void main(String[] args){
    Parents parents = new Parents();
    parents.setBirthday("1-1");

    School school = new School();
    EducationBureau educationBureau = new EducationBureau();
    PoliceStation policeStation = new PoliceStation();
    Hospital hospital = new Hospital();
    school.setNext(educationBureau).setNext(policeStation).setNext(hospital);
    school.operation(parents);
}

输出结果:
没有学籍证明,需要去教育局办理
---学校不能处理此问题,下一级处理
没有户口本,需派出所办理
---教育局不能处理此问题,下一级处理
没有出生证明,需医院开证明
---派出所不能处理此问题,下一级处理
没有出生证明,开一个出生证明
---医院能处理此问题
---派出所的下一级处理成功,本级再次处理
有出生证明,办理户口本
---教育局的下一级处理成功,本级再次处理
有户口本,可以办理学籍
---学校的下一级处理成功,本级再次处理
有学籍证明,可以入学

再来看一个孩子没有出生日期的父母

public static void main(String[] args){
    Parents parents = new Parents();

    School school = new School();
    EducationBureau educationBureau = new EducationBureau();
    PoliceStation policeStation = new PoliceStation();
    Hospital hospital = new Hospital();
    school.setNext(educationBureau).setNext(policeStation).setNext(hospital);
    school.operation(parents);
}

输出结果:
没有学籍证明,需要去教育局办理
---学校不能处理此问题,下一级处理
没有户口本,需派出所办理
---教育局不能处理此问题,下一级处理
没有出生证明,需医院开证明
---派出所不能处理此问题,下一级处理
不知道出生日期,不给开出生证明
---医院已经是最后一级
失败-医院不给开出生证明
---派出所的下一级处理失败
失败-没有出生证明,医院不给开证明
---教育局的下一级处理失败
失败-没有户口本,派出所办不给办理
---学校的下一级处理失败
失败-没有学籍证明,教育局不给办理

这样我们就可以看到,以及以及来处理,每一级的处理都只关联到下一级,除了知道下一级之外,对其他的对想都毫无所知。

熟悉的同学可能发现,这个非常像android中事件的处理机制。没错,android中的事件处理的确也是这样的,只不过android中的事件处理其阿里,比我们这里的简答的demo要复杂一些,处理了很多不同类型的事件,也有拦截的功能,有兴趣的同学可以了解一下android的事件传递机制。

链式的结构可以是一条链,可以是一个树,还可以是一个环,模式是不约束这个的,只要自己去实现就行,但是,在一个时刻,只能由一个对象传给另一个对象处理,不能同时传给多个对象来处理。

事件的开始,我们只交给第一个对象来处理,至于后面谁来处理的,我们就不关心了,解耦事件最终处理和请求处理的人之间的关系,如果不采用这种方法,那请求处理的人,就必须知道所有的环节的功能,这在现实中其实基本是不可能的。

责任链模式,还可以动态的修改事件处理顺序,拥有非常良好的扩展性,处理环节之间,也是解耦的,只关心自己的部分。

但是,因为处理事件在链上传递,需要一个一个的寻找,需要花费一定的时间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值