Java中职责链的泛化使用

1 概述

本文基于自行车安装的例子说明职责链模式的非泛化及泛化实现。最终演示如何通过一条职责链将多个不同类型的处理结点组织在一起处理不同的输入。

2 职责链模式的非泛化的实现

假设我们要对自行车安装,自行车由链条、座椅、轮子三部分组成。首先定义我们用到的自行车类。

    class Bycicle {
    }

接着定义抽象处理器,用来完成职责链的组装及执行。

    abstract class Handler {
        public Handler(Handler handler) {
            this.next = handler;
        }

        private Handler next;

        protected abstract void installInner(Bycicle bycicle);

        protected void install(Bycicle bycicle) {
            installInner(bycicle);
            if(next != null) {
                next.install(bycicle);
            }
        }
    }

最后定义我们用的三个零件安装器。

    class WheelHandler extends Handler{

        public WheelHandler(Handler handler) {
            super(handler);
        }

        @Override
        protected void installInner(Bycicle bycicle) {
            System.out.println("安装轮子");
        }
    }

    class ChainHandler extends Handler{

        public ChainHandler(Handler handler) {
            super(handler);
        }

        @Override
        protected void installInner(Bycicle bycicle) {
            System.out.println("安装链条");
        }
    }

    class SeatHandler extends Handler{

        public SeatHandler(Handler handler) {
            super(handler);
        }

        @Override
        protected void installInner(Bycicle bycicle) {
            System.out.println("安装座椅");
        }
    }

上述工作完毕后,进行指责链建立,并执行安装工作。

    @Test
    public void test3() {
        Handler wheelHandler = new WheelHandler(null);
        Handler chainHandler = new ChainHandler(wheelHandler);
        Handler seatHandler = new SeatHandler(chainHandler);
        Bycicle bycicle = new Bycicle();
        seatHandler.install(bycicle);
    }

执行完毕后可看到如下输出:

安装座椅
安装链条
安装轮子

那么这就是一个最简单的职责链的演示,输入接收同一种类型参数,最终各个结点完成对参数的处理。

2 职责链模式的泛化的实现

假设我们用有新的车型,三轮自行车和电动自行车。当我们要将职责链应用到不同类型参数上时,需要通过泛化来实现。

首先定义引入的新车型。

    class Bycicle {
        Bycicle(String name) {
            this.name = name;
        }
        private String name;
        ...
    }

    /**
     * 电动自行车
     */
    class ElectricBycicle extends Bycicle{
        public ElectricBycicle() {
            super("电动自行车");
        }
    }

    /**
     * 三轮自行车
     */
    class Tricycle extends Bycicle{
        public Tricycle() {
            super("三轮自行车");
        }
    }

其次对抽象处理器进行类型化改造。

    abstract class Handler<T extends Bycicle> {
        public Handler(Handler<T> handler) {
            this.next = handler;
        }

        private Handler<T> next;

        protected abstract void installInner(T bycicle);

        protected void install(T bycicle) {
            installInner(bycicle);
            if(next != null) {
                next.install(bycicle);
            }
        }

        protected void install0(T bycicle) {
            if(next != null) {
                next.install(bycicle);
            }
        }
    }

最后定义具体车型的处理器。

   class WheelHandler extends Handler<Tricycle>{

        public WheelHandler(Handler<Tricycle> handler) {
            super(handler);
        }

        @Override
        protected void installInner(Tricycle bycicle) {
            System.out.println("安装" + bycicle.getName() + "轮子");
        }
    }

    class ChainHandler extends Handler<Tricycle>{

        public ChainHandler(Handler<Tricycle> handler) {
            super(handler);
        }

        @Override
        protected void installInner(Tricycle bycicle) {
            System.out.println("安装" + bycicle.getName() + "链条");
        }
    }

    class SeatHandler extends Handler<Tricycle>{

        public SeatHandler(Handler<Tricycle> handler) {
            super(handler);
        }

        @Override
        protected void installInner(Tricycle bycicle) {
            System.out.println("安装"+ bycicle.getName() + "座椅");
        }
    }

最后创建我们需要的处理器并进行组装即可。当我们需要处理其它类型的车时,创建相应处理器并组装执行即可。

    @Test
    public void test3() {
        Handler<Tricycle> wheelHandler = new WheelHandler(null);
        Handler<Tricycle> chainHandler = new ChainHandler(wheelHandler);
        Handler<Tricycle> seatHandler = new SeatHandler(chainHandler);
        Tricycle bycicle = new Tricycle();
        seatHandler.install(bycicle);
    }

最终输出如下:

安装三轮自行车座椅
安装三轮自行车链条
安装三轮自行车轮子

3 职责链中包含多种不同类型的处理结点

假设自行车、三轮车、电动自行车的处理过程含有一些公用行为。那么我们希望将这些公用自行和不同自行车的特殊行为组织在一条链中。当某个处理结点不是对应类型车的处理器那么跳过,如果是则执行。

首先我们对抽象处理器进行改造。为了使不同处理器串联在一起,我们在「变化点1」构造时链表时使用了Handler类。其次在变化点2对install进行改造。因为当不同类型参数传递给处理器,如果类型不匹配则会出现类型错误的问题。因此当类型匹配时才执行当前结点,否则跳过当前,执行下一个结点。

   abstract class Handler<T extends Bycicle> {
        public Handler(Handler handler) {
            this.next = handler;
        }

        private Handler next;

        protected abstract void installInner(T bycicle);

        protected void install(T bycicle) {
            Class<?> actualTypeArgument = ( Class<?>)((ParameterizedType) this.getClass().getGenericSuperclass())
                .getActualTypeArguments()[0];
            if(actualTypeArgument.isInstance(bycicle)) {
                //noinspection unchecked
                installInner(bycicle);
                invokeNext(next,bycicle);
            } else {
                invokeNext(next,bycicle);
            }
        }

        private void invokeNext(Handler next,T bycicle) {
            if (next != null) {
                next.install(bycicle);
            }
        }
    }

其次我们新增两个公共行为支付与交付。支付与交付对与任何类型的自行车都通用。

    class PayHandler extends Handler<Bycicle>{

        public PayHandler(Handler handler) {
            super(handler);
        }

        @Override
        protected void installInner(Bycicle bycicle) {
            System.out.println("支付");
        }
    }

    class DeliveryHandler extends Handler<Bycicle>{

        public DeliveryHandler(Handler<Bycicle> handler) {
            super(handler);
        }

        @Override
        protected void installInner(Bycicle bycicle) {
            System.out.println("交付");
        }
    }

最后我们将支付、安装电动自行车车轮、安装三轮车车轮、交付组装在一起形成一条链。

        Handler<Bycicle> deliveryHandler = new DeliveryHandler(null);
        Handler<ElectricBycicle> eBycicleWheelHandler = new ElectricBycicleWheelHandler(deliveryHandler);
        Handler<Tricycle> tricycleWheelHandler = new TricycleWheelHandler(eBycicleWheelHandler);
        Handler<Bycicle> payHandler = new PayHandler(tricycleWheelHandler);


        System.out.println("====ebycicle====");
        payHandler.install(new Tricycle());
        System.out.println("====tricicle====");
        payHandler.install(new ElectricBycicle());

最终输出可以看到,通过一条链完成公共行为与差异化行为的执行。

====ebycicle====
支付
安装三轮自行车轮子
交付
====tricicle====
支付
安装电动自行车轮子
交付

4 总结

职责链通过将处理行为拆分成不同的处理结点,使得代码更简洁清晰。如果要应用到不同类型上则需要结合泛型来完成。当一条链中不同的结点需要处理不同类型的参数则在执行前需要检查参数类型与处理器处理类型是否匹配,从而避免错误发生。

5 参考

[1]netty io.netty.channel.SimpleChannelInboundHandler实现

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值