Java中职责链的泛化使用

Posted FserSuN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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实现

以上是关于Java中职责链的泛化使用的主要内容,如果未能解决你的问题,请参考以下文章

Uber要研发自动驾驶自行车和滑板车了?为什么?怎么实现?

RFID 电动二轮自行车的防盗系统—读头

职责链的应用

RFID 电动二轮自行车的防盗系统—读头

电动自行车如何过马路?规定:下车推行!

UML图中类之间的关系:依赖,泛化,关联,聚合,组合,实现