Java设计模式--责任链模式

1 Chain of Responsibility Pattern 责任链模式

目的:弱化请求方与处理方的关联关系,让双方各自都成为可复用的组件;
实现:拦截的类都实现统一接口,将多个对象组成一条责任链,然后按照他们在职责上的顺序一个一个的找出来谁来负责处理。

1.责任链上的处理者负责处理请求,客户只需要将请求发送到职责链上即可,无须关心请求的处理细节和请求的传递;
2.每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。

2 实现

代码场景:手机生产流水线车间里,不同组件的流水线工人会对其安装cpu、camera和ram等部件。
1.被处理对象手机
2.抽象处理者流水线
3.具体处理者不同组件的工人

2.1 代码实现

抽象处理者角色:AssemblyWorker(组装工人)

public abstract class AssemblyWorker {
    //责任链关键 下一个工人
    protected AssemblyWorker nextWorker;
    protected MobilePhone mobilePhone;

    public AssemblyWorker(MobilePhone mobilePhone) {
        this.mobilePhone = mobilePhone;
    }
    public abstract void assembling();
    //设定下一个工人
    public void setNextWorker(AssemblyWorker nextWorker) {
        this.nextWorker = nextWorker;
    }

}

具体处理者角色:CpuWorker (CPU组装工人)

public class CpuWorker extends AssemblyWorker {

    private final String name = "CPU组装工人";
    public CpuWorker(MobilePhone mobilePhone) {
        super(mobilePhone);
    }

    @Override
    public void assembling() {
        if (null == mobilePhone.getCpu()) {
            mobilePhone.setCpu("高通骁龙8");
            System.out.println(name + "将CPU给手机组装上了");
        }
        if (null != nextWorker) {
            nextWorker.assembling();
        }
    }
}

具体处理者角色:CpuWorker (摄像头组装工人)

public class CameraWorker extends AssemblyWorker {

    private final String name = "摄像头组装工人";
    public CameraWorker(MobilePhone mobilePhone) {
        super(mobilePhone);
    }

    @Override
    public void assembling() {
        if (null == mobilePhone.getCamera()) {
            mobilePhone.setCamera("索尼2400万像素摄像头");
            System.out.println(name + "将摄像头给手机组装上了");
        }
        if (null != nextWorker) {
            nextWorker.assembling();
        }
    }
}

具体处理者角色:RamWorker(运行内存组装工人)

public class RamWorker extends AssemblyWorker {

    private final String name = "运行内存组装工人";

    public RamWorker(MobilePhone mobilePhone) {
        super(mobilePhone);
    }

    @Override
    public void assembling() {
        if (null == mobilePhone.getRam()) {
            mobilePhone.setRam("DDR4 8G 运行内存");
            System.out.println(name + "运行内存给手机组装上了");
        }
        if (null != nextWorker) {
            nextWorker.assembling();
        }
    }
}

2.2 涉及角色

在职责链模式结构图中包含如下几个角色:

Handler(抽象处理者):它定义了一个处理请求的接口,一般设计为抽象类,由于不同的具体处理者处理请求的方式不同,因此在其中定义了抽象请求处理方法。因为每一个处理者的下家还是一个处理者,因此在抽象处理者中定义了一个抽象处理者类型的对象(如结构图中的 successor),作为其对下家的引用。通过该引用,处理者可以连成一条链。

ConcreteHandler(具体处理者):它是抽象处理者的子类,可以处理用户请求,在具体处理者类中实现了抽象处理者中定义的抽象请求处理方法,在处理请求之前需要进行判断,看是否有相应的处理权限,如果可以处理请求就处理它,否则将请求转发给后继者;在具体处理者中可以访问链中下一个对象,以便请求的转发。

2.3 调用

调用者:

public class Client {
    public static void main(String[] args) {
        //对一个什么都没有的手机进行组装
        MobilePhone mp = new MobilePhone();
        AssemblyWorker cpuWorker = new CpuWorker(mp);
        AssemblyWorker cameraWorker = new CameraWorker(mp);
        AssemblyWorker ramWorker = new RamWorker(mp);
        cpuWorker.setNextWorker(cameraWorker);
        cameraWorker.setNextWorker(ramWorker);

        cpuWorker.assembling();
        mp.show();
        System.out.println("-------------------------");

        //对一个已经存在CPU的手机进行组装
        MobilePhone mp1 = new MobilePhone();
        mp1.setCpu("Intel");
        AssemblyWorker cpuWorker1 = new CpuWorker(mp1);
        AssemblyWorker cameraWorker1 = new CameraWorker(mp1);
        AssemblyWorker ramWorker1 = new RamWorker(mp1);
        cpuWorker1.setNextWorker(cameraWorker1);
        cameraWorker1.setNextWorker(ramWorker1);

        cpuWorker1.assembling();
        mp1.show();
    }
}

结果:

CPU组装工人将CPU给手机组装上了
摄像头组装工人将摄像头给手机组装上了
运行内存组装工人运行内存给手机组装上了
该手机的CPU为[高通骁龙8],Camera为[索尼2400万像素摄像头],RAM为[DDR4 8G 运行内存]
-------------------------
摄像头组装工人将摄像头给手机组装上了
运行内存组装工人运行内存给手机组装上了
该手机的CPU为[Intel],Camera为[索尼2400万像素摄像头],RAM为[DDR4 8G 运行内存]

Java设计模式汇总:点击跳转
代码地址:点击跳转

参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值