方法入参很复杂,每次调用都要构造BO入参?一招教你自动构造入参

本文介绍了如何通过适配器模式优化代码中频繁构建复杂方法参数的问题。作者以计算订单价格为例,展示了如何将方法入参定义为接口,让不同数据来源的类实现该接口,从而避免重复构建参数。这种方式不仅减少了重复代码,还引入了设计模式,提高了代码的可读性和可维护性。
摘要由CSDN通过智能技术生成

场景

同在互联网打工的小伙伴们肯定都面临这样一种场景:

通用逻辑(被多处调用)我们通常会封装成一个方法,那这个方法入参正常来说都不会少,(在开发规范中,经常会看到一条"方法入参正常不超过3个”。)面对入参超过3个的方法我们正常都会封装成一个bo类(这样扩展方法入参,再也不怕被领导diss了)。

如下图,假设现在有三个逻辑需要去调用这个方法,我们是不是都需要去build入参呀,这也是很多小伙伴会选择的调用方式。
在这里插入图片描述

大家都知道,在咱们这个行业最不缺的就是挑刺儿的人,这些人经常也被称为有工匠精神的码农哈哈哈!!!

那么就有工匠精神的码农看不惯红框内的代码的(怎么看都是重复代码),每次调用方法都去build入参,太麻烦了!!!

连调用方法都嫌传参麻烦,难道这就是有工匠精神的码农?
不能理解!!!
不过倒也挺好奇究竟是怎么做到自动构造参数的,所以也就有了本篇文章。
在这里插入图片描述

优化

现在我们假设上面提到的那个方法是一个订单价格的方法,其实这是我最近遇到的一个真实业务场景:
这里我们只需要了解影响订单价格的因素有订单明细单价工艺单价价格类型订单明细长宽高,以及对应明细下单数量。面对这么多参数,而且这个方法很多地方用到,每个地方去构建参数确实是比较麻烦。
那怎么去做到自动构建入参呢,接下来就是文章的重点了。

  1. 我们首先要思考一个问题,这些参数的源头是哪里呢?
    (1)可能是下单时候前端传过来的参数。(controller层用XXXDTO接收)
    (2)也可能是修改某个订单明细导致订单价格须重新计算,那这个时候需要从数据库查询该订单其他订单明细重新计算,这个时候我们定义XXXPOJO类接收查询结果。(这个为啥不是entity呢,因为这些参数来自不同的实体类)
    这里扯多了,不理解上面场景的小伙伴,可以理解成入参来自不同的类。
  2. 参数来自不同的类,而这个方法又得去兼容这多个类。

面对这样的场景我们不禁联想到万能数据线。Type-C接口、苹果接口、安卓接口共同连接着USB接口,USB接口才是连接电源的入口。至于这三种接口怎么和USB连接才可以工作就是线内部要做事情了,外部只要关心不同类型手机对应不同的接口就可以了。
大家仔细品一下上面这个我们再常见不过的例子,我觉得太能类比到我们这个场景了。

(1) Type-C接口、苹果接口、安卓接口 --> 想调用方法的不同类(不同数据来源)
(2) USB接口 --> 方法入参
(3) 电源 --> 方法主体

在这里插入图片描述

也就是说我们要让这多个类与入参产生关联才可以无缝调用方法主体。

  1. 我们不妨把方法的入参定义成一个接口Adapter形式(接口定义各个我们上面说的决定订单价格因素的获取方法),那么这样不同类(数据来源)就可以去实现这个接口,必定重写方法,这就相当于把构建入参的操作移到dto去做

上面可能说的太抽象了,所以给大家再上个图,看一下具体结构
在这里插入图片描述
光说光看,还不如来个实操理解快呢,早知道会这么想,接下来,上代码!!!

/**
 * 方法入参
 */
public interface OrderAmountCalAdapter {
    /**
     * 单价 单位:分
     */
    BigDecimal obtainPrice();

    /**
     * 工艺单价 单位:分
     */
    BigDecimal obtainCraftPrice();

    /**
     * 价格类型 2平方价格 3立方价格
     */
    Integer obtainPriceType();

    /**
     * 长度 单位:毫米 mm
     */
    Integer obtainLength();

    /**
     * 宽度 单位:毫米 mm
     */
    Integer obtainWidth();

    /**
     * 厚度 单位:毫米 mm
     */
    Integer obtainHeight();
}

/**
 * 计算方法
 */
public long calculate(OrderAmountCalAdapter adapter, Integer qty) {
	    if (adapter == null) {
	        throw new ApiException("计算订单金额时载体对象不能为空");
	    }
	    if (adapter.obtainPrice() == null) {
	        throw new ApiException("计算订单金额时金额不能为空");
	    }
	    if (adapter.obtainPriceType() == null) {
	        throw new ApiException("计算订单金额时价格类型不能为空");
	    }
	    if (adapter.obtainLength() == null || adapter.obtainWidth() == null || adapter.obtainHeight() == null) {
	        throw new ApiException("计算订单金额时商品属性信息不能为空");
	    }
	    if (qty == null) {
	        throw new ApiException("计算订单金额时数量不能为空");
	    }
	
	    return doCalculate(adapter, qty).longValue();
}
/**
 * 不同DTO类,通过实现OrderAmountCalAdapter接口,重写方法获取DTO属性值,也就是上面说的把构建入参移到具体的DTO类来做
 */
@Data
public class OrderProductProperty implements OrderAmountCalAdapter {

    @ApiModelProperty(value = "明细ID")
    private Long id;

    @ApiModelProperty(value = "明细单价")
    private Long price;

    @ApiModelProperty(value = "下单数量")
    private Integer orderQuantity;

    @ApiModelProperty(value = "工艺单价")
    private Long craftPrice;

    @ApiModelProperty(value = "长度(单位mm)")
    private Integer length;

    @ApiModelProperty(value = "宽度(单位mm)")
    private Integer width;

    @ApiModelProperty(value = "高度(单位mm)")
    private Integer height;

    @ApiModelProperty("价格类型 2平方 3立方")
    private Integer priceType;


    @Override
    public BigDecimal obtainPrice() {
        return BigDecimal.valueOf(getPrice() == null ? 0L : getPrice());
    }

    @Override
    public BigDecimal obtainCraftPrice() {
        return BigDecimal.valueOf(getCraftPrice() == null ? 0L : getCraftPrice());
    }

    @Override
    public Integer obtainPriceType() {
        return getPriceType();
    }

    @Override
    public Integer obtainLength() {
        return getLength();
    }

    @Override
    public Integer obtainWidth() {
        return getWidth();
    }

    @Override
    public Integer obtainHeight() {
        return getHeight();
    }

}

这就达到我们上面所说的不用构建方法的入参就可以调用方法了,是不是很精妙哈哈哈。

其实仔细想一想,这不就是适配者设计模式。

适配器模式的主要作⽤就是把原本不兼容的接⼝,通过适配修改做到统⼀。

原本只是想说偷个懒,没想到不知不觉还用上了设计模式,代码b格一下提高了,leader连忙称赞小伙子不错不错!

总结

其实本文说的招数,其实就是适配器模式,相信大家也理解到这么做的好处了。

在业务开发中我们会经常的需要做不同接⼝或者方法的兼容,那么这个时候就要想到适配器模式。

设计模式其实是前辈们开发中总结的一下通用范式,我们要合理的学习每种设计模式适合场景,解决什么问题。也不要因设计模式而在写代码时强行使用。

在面对各种各样的开发场景,我们要多思考,多沉淀,才可以让自己的代码更优雅,更好扩展。

加油打工人!奥利给😎

我是rose,感谢各位的观看,各位的点赞就是rose输出的最大动力,我们下篇文章见!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值