使用责任链模式重构原有的一段代码

 接手的旧项目中有一段定位网段的代码,逻辑是 先匹配自定义网段->再匹配内置网段->最后是未知网段,使用责任链模式后类图如下:

 

责任连的顶级处理类handler:

/**
 * @author dxy
 * @descrition 网段定位处理器
 */
public abstract class Handler<T> {
    protected Handler next;

    public void next(Handler next) {
        this.next = next;
    }

    /**
     * 钩子方法1 不带标记的
     * @param result
     * @param originBigIntIp
     * @param ip
     * @param intranetIpNetworkSegmentService
     */
    public abstract IntranetIpNetworkSegment doHandler(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService);

    /**
     *
     * @param result
     * @param originBigIntIp
     * @param ip
     * @param state
     * @param intranetIpNetworkSegmentService
     * @return
     */
    public abstract IntranetIpNetworkSegment doHandlerWithFlag(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state);

    public static class Builder<T> {
        private Handler<T> head;
        private Handler<T> tail;

        public Builder<T> addHandler(Handler handler) {
            if (this.head == null) {
                this.head = this.tail = handler;
                return this;
            }
            this.tail.next(handler);
            this.tail = handler;
            return this;
        }

        public Handler<T> build() {
            return this.head;
        }
    }
}

自定义网段处理:

/**
 * @author dxy
 * @descrition 自定义网段匹配处理器
 */
public class CustomNetSegHandler extends Handler {
    @Override
    public IntranetIpNetworkSegment doHandler(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService) {
        result = getIntranetIpNetworkSegment(result, originBigIntIp, intranetIpNetworkSegmentService, null);
        //这里已经定位到网端 不向下传递
        if (result != null) {
            return result;
        } else {
            //这里交给下个个责任链
            return next.doHandler(result, originBigIntIp, ip, intranetIpNetworkSegmentService);
        }
    }

    @Override
    public IntranetIpNetworkSegment doHandlerWithFlag(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
        result = getIntranetIpNetworkSegment(result, originBigIntIp, intranetIpNetworkSegmentService, state);
        //这里已经定位到网端 不向下传递
        if (result != null) {
            return result;
        } else {
            //这里交给下个个责任链
            return next.doHandlerWithFlag(result, originBigIntIp, ip, intranetIpNetworkSegmentService, state);
        }
    }

    /**
     * 共用的定位网段方法
     *
     * @param result
     * @param originBigIntIp
     * @param intranetIpNetworkSegmentService
     * @param state
     * @return
     */
    private IntranetIpNetworkSegment getIntranetIpNetworkSegment(IntranetIpNetworkSegment result, BigInteger originBigIntIp, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
        // 现有的自定义网段,转化为两个端点的set
        LinkedHashSet<IntranetIpNetworkSegmentServiceImpl.BigIntNetSeg> allCustomNetSegs = intranetIpNetworkSegmentService.getAllIpSet(Arrays.asList(CUSTOM_INTRANET_NETWORK_SEGMENT_ID));
        //遍历netSeg
        for (IntranetIpNetworkSegmentServiceImpl.BigIntNetSeg netSeg : allCustomNetSegs) {
            //参数ip在网段范围内
            if (intranetIpNetworkSegmentService.isInNetSeg(originBigIntIp, netSeg)) {
                result = intranetIpNetworkSegmentService.findById(netSeg.getNetSegId());
            }
        }
        return result;
    }
}

内置网段处理:

/**
 * @author dxy
 * @descrition 内置网段处理
 */
public class InnerAbcNetSegHandler extends Handler {
    @Override
    public IntranetIpNetworkSegment doHandler(IntranetIpNetworkSegment result, BigInteger originBigIntIp,String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService) {
        //这里说明自定义网段 没有匹配到 匹配abc
        result = getIntranetIpNetworkSegment(result, originBigIntIp, intranetIpNetworkSegmentService, null);
        //这里已经定位到网端 不向下传递
        if (result != null) {
            return result;
        } else {
            //这里交给下个个责任链
            return next.doHandler(result, originBigIntIp, ip, intranetIpNetworkSegmentService);
        }
    }

    @Override
    public IntranetIpNetworkSegment doHandlerWithFlag(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
        result = getIntranetIpNetworkSegment(result, originBigIntIp, intranetIpNetworkSegmentService, state);
        //这里已经定位到网端 不向下传递
        if (result != null) {
            return result;
        } else {
            //这里交给下个个责任链
            return next.doHandlerWithFlag(result, originBigIntIp, ip, intranetIpNetworkSegmentService, state);
        }
    }


    private IntranetIpNetworkSegment getIntranetIpNetworkSegment(IntranetIpNetworkSegment result, BigInteger originBigIntIp, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService,State state) {
        if (result == null) {
            LinkedHashSet<IntranetIpNetworkSegmentServiceImpl.BigIntNetSeg> innerNetSegs = intranetIpNetworkSegmentService.getAllIpSet(Arrays.asList(A_INTRANET_NETWORK_SEGMENT_ID, B_INTRANET_NETWORK_SEGMENT_ID, C_INTRANET_NETWORK_SEGMENT_ID));
            //遍历netSeg
            for (IntranetIpNetworkSegmentServiceImpl.BigIntNetSeg netSeg : innerNetSegs) {
                //参数ip在网段范围内
                if (intranetIpNetworkSegmentService.isInNetSeg(originBigIntIp, netSeg)) {
                    result = intranetIpNetworkSegmentService.findById(netSeg.getNetSegId());
                }
            }
        }
        return result;
    }
}

未知网段处理:

/**
 * @author dxy
 * @descrition 未知网段处理
 */
public class UnknownNetSegHandler extends Handler {
    @Override
    public IntranetIpNetworkSegment doHandler(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService) {
        return getIntranetIpNetworkSegment(result, ip, intranetIpNetworkSegmentService, null);
    }

    private IntranetIpNetworkSegment getIntranetIpNetworkSegment(IntranetIpNetworkSegment result, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
        //这里说明自定义网段 abc 都没有匹配到 放未知 并建立网段
        if (result == null) {
            if (ValidateUtil.isIpv6(ip)) {
                int defaultMaskBit = 64;
                result = new IntranetIpNetworkSegment();
                String ipv6Network = ip + Ipv4Util.IP_MASK_SPLIT_MARK + defaultMaskBit;
                IPv6Network network = IPv6Network.fromString(ipv6Network);
                String netSegBeginIp = network.getFirst().toLongString();
                String netSegEndIp = network.getLast().toLongString();
                //检查是否和当前网段重复 & 合法(前面小于后面)
                boolean isRight = checkNetSegCorrect(netSegBeginIp, netSegEndIp);
                Assert.isTrue(isRight, "输入的网段不合法!");
                if (intranetIpNetworkSegmentService.checkDuplicateIp(netSegBeginIp, netSegEndIp)) {
                    //没问题,创建64位子网前缀
                    result.setSecurityDomainId(ProjectConstant.UNKNOWN_SEC_DOM_ID);
                    result.setNetworkSegmentName(ipv6Network);
                    result.setNetworkSegmentStartIp(netSegBeginIp);
                    result.setNetworkSegmentStopIp(netSegEndIp);
                } else {
                    //如果重复了
                    result.setSecurityDomainId(ProjectConstant.UNKNOWN_SEC_DOM_ID);
                    result.setNetworkSegmentName(ip + Ipv4Util.IP_MASK_SPLIT_MARK + 128);
                    result.setNetworkSegmentStartIp(ip);
                    result.setNetworkSegmentStopIp(ip);
                }
            } else {//ipv4的情况下
                int defaultMaskBit = 24;
                // 如果没有匹配到,在未知安全域下建立网段,并返回ID,关联起来
                String netSegBeginIp = Ipv4Util.getBeginIpStr(ip, defaultMaskBit);
                String netSegEndIp = Ipv4Util.getEndIpStr(ip, defaultMaskBit);
                result = new IntranetIpNetworkSegment();
                //检查是否和当前网段重复 & 合法
                boolean isRight = checkNetSegCorrect(netSegBeginIp, netSegEndIp);
                Assert.isTrue(isRight, "输入的网段不合法!");
                if (intranetIpNetworkSegmentService.checkDuplicateIp(netSegBeginIp, netSegEndIp)) {
                    //没问题,创建24位掩码网段
                    result.setSecurityDomainId(ProjectConstant.UNKNOWN_SEC_DOM_ID);
                    result.setNetworkSegmentName(ip + Ipv4Util.IP_MASK_SPLIT_MARK + defaultMaskBit);
                    result.setNetworkSegmentStartIp(netSegBeginIp);
                    result.setNetworkSegmentStopIp(netSegEndIp);
                } else {
                    //如果重复了
                    result.setSecurityDomainId(ProjectConstant.UNKNOWN_SEC_DOM_ID);
                    result.setNetworkSegmentName(ip + Ipv4Util.IP_MASK_SPLIT_MARK + 32);
                    result.setNetworkSegmentStartIp(ip);
                    result.setNetworkSegmentStopIp(ip);
                }
            }
            if (state != null) {
                result.setDataSourceFlag(state);
            }
            intranetIpNetworkSegmentService.save(result);
        }
        return result;
    }

    @Override
    public IntranetIpNetworkSegment doHandlerWithFlag(IntranetIpNetworkSegment result, BigInteger originBigIntIp, String ip, IntranetIpNetworkSegmentServiceImpl intranetIpNetworkSegmentService, State state) {
        return getIntranetIpNetworkSegment(result, ip, intranetIpNetworkSegmentService, state);
    }
}

使用:

//这里改成责任链调用
Handler.Builder builder = new Handler.Builder();

builder.addHandler(new CustomNetSegHandler())
       .addHandler(new InnerAbcNetSegHandler())
       .addHandler(new UnknownNetSegHandler());

result = builder.build().doHandler(result, originBigIntIp, ip, this);
log.debug("--定位到的网段:--" + result);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焱童鞋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值