优秀的后端应该有哪些开发习惯?

前言毕业快三年了,前后也待过几家公司,碰到各种各样的同事 。见识过各种各样的代码,优秀的、垃圾的、不堪入目的、看了想跑路的等等,所以这篇文章记录一下一个优秀的后端 JAVA 开发应该有哪些好的开发习惯 。
拆分合理的目录结构受传统的 MVC 模式影响,传统做法大多是几个固定的文件夹 controller、service、mApper、entity,然后无限制添加,到最后你就会发现一个 service 文件夹下面有几十上百个 Service 类,根本没法分清业务模块 。正确的做法是在写 service 上层新建一个 modules 文件夹,在 moudles 文件夹下根据不同业务建立不同的包,在这些包下面写具体的 service、controller、entity、enums 包或者继续拆分 。

优秀的后端应该有哪些开发习惯?

文章插图
 

优秀的后端应该有哪些开发习惯?

文章插图
 
等以后开发版本迭代,如果某个包可以继续拆领域就继续往下拆,可以很清楚的一览项目业务模块 。后续拆微服务也简单 。
封装方法形参当你的方法形参过多时请封装一个对象出来...... 下面是一个反面教材,谁特么教你这样写代码的!
public void updateCustomerDeviceAndInstallInfo(long customerId, String channelKey,String AndroidId, String imei, String gaId,String gcmPushToken, String instanceId) {}复制代码写个对象出来
public class CustomerDeviceRequest {private Long customerId;//省略属性......}复制代码为什么要这么写?比如你这方法是用来查询的,万一以后加个查询条件是不是要修改方法?每次加每次都要改方法参数列表 。封装个对象,以后无论加多少查询条件都只需要在对象里面加字段就行 。而且关键是看起来代码也很舒服啊!
封装业务逻辑如果你看过“屎山”你就会有深刻的感触,这特么一个方法能写几千行代码,还无任何规则可言......往往负责的人会说,这个业务太复杂,没有办法改善,实际上这都是懒的借口 。不管业务再复杂,我们都能够用合理的设计、封装去提升代码可读性 。下面贴两段高级开发(假装自己是高级开发)写的代码
@Transactionalpublic ChildOrder submit(Long orderId, OrderSubmitRequest.Shop shop) {ChildOrder childOrder = this.generateOrder(shop);childOrder.setOrderId(orderId);//订单来源 APP/微信小程序childOrder.setSource(userService.getOrderSource());// 校验优惠券orderAdjustmentService.validate(shop.getOrderAdjustments());// 订单商品orderProductService.add(childOrder, shop);// 订单附件orderAnnexService.add(childOrder.getId(), shop.getOrderAnnexes());// 处理订单地址信息processAddress(childOrder, shop);// 最后插入订单childOrderMapper.insert(childOrder);this.updateSkuInventory(shop, childOrder);// 发送订单创建事件applicationEventPublisher.publishEvent(new ChildOrderCreatedEvent(this, shop, childOrder));return childOrder;}复制代码@Transactionalpublic void clearBills(Long customerId) {// 获取清算需要的账单、deposit等信息ClearContext context = getClearContext(customerId);// 校验金额合法checkAmount(context);// 判断是否可用优惠券,返回可抵扣金额CouponDeductibleResponse deductibleResponse = couponDeducted(context);// 清算所有账单DepositClearResponse response = clearBills(context);// 更新 l_pay_depositlPayDepositService.clear(context.getDeposit(), response);// 发送还款对账消息repaymentService.sendVerifyBillMessage(customerId, context.getDeposit(), EventName.DEPOSIT_SUCCEED_FLOW_REMINDER);// 更新账户余额accountService.clear(context, response);// 处理清算的优惠券,被用掉或者解绑couponService.clear(deductibleResponse);// 保存券抵扣记录clearCouponDeductService.add(context, deductibleResponse);}复制代码这段两代码里面其实业务很复杂,内部估计保守干了五万件事情,但是不同水平的人写出来就完全不同,不得不赞一下这个注释,这个业务的拆分和方法的封装 。一个大业务里面有多个小业务,不同的业务调用不同的 service 方法即可,后续接手的人即使没有流程图等相关文档也能快速理解这里的业务,而很多初级开发写出来的业务方法就是上一行代码是 A 业务的,下一行代码是 B业务的,在下面一行代码又是 A 业务的,业务调用之间还嵌套这一堆单元逻辑,显得非常混乱,代码还多 。
判断集合类型不为空的正确方式很多人喜欢写这样的代码去判断集合
if (list == null || list.size() == 0) {return null;}复制代码当然你硬要这么写也没什么问题......但是不觉得难受么,现在框架中随便一个 jar 包都有集合工具类,比如
org.springframework.util.CollectionUtils、com.baomidou.mybatisplus.core.toolkit.CollectionUtils。以后请这么写


推荐阅读