代码粒度思考

本贴最后更新于 1923 天前,其中的信息可能已经事过景迁

为什么要划分粒度?

  1. 减少用户等待时间,节省性能。
  2. 提高安全性,减少不必要的信息暴露
  3. 提高复用性,降低开发和维护成本
  4. 利于单元测试

粗粒度和细粒度

信息数量超过业务需要的信息数量,为粗粒度

信息数量少于业务需要信息数量,为细粒度

划分太粗

  1. 性能差
  2. 安全性差

划分太细

  1. 开发和维护性成本高
  2. 单元测试成本高

粒度取舍

粗粒度和细粒度并不矛盾,两者可以同时存在。

细粒度可以提高复用性,粗粒度可以减少重复计算以及方便业务扩展。

粒度分类

Mapper 的粒度

如果是按照主键查询某个商品,
针对频繁使用的字段和全部字段分别写两个 Mapper。
写一个
只有 id 和商品名的 Mapper 和
全部信息都包括的 Mapper

频繁 的界限是按照业务以及经验来的。

服务的粒度

服务的方法粒度是根据业务逻辑来划分的。
比如订单微服务中,订单服务,退款服务,对账服务,分账服务等等。

服务方法的粒度

假设我需要一个查询以及增加订单的功能,同时希望能在订单列表展示订单金额,在订单详情展示支付方式。

提供细粒度的服务方法,对应 Mapper 的接口,因为 Mapper 接口不能写实现,所以此方法中提供业务无关的内容,比如批量插入时的 po 集合,如果为空就打个 log 然后 return,以及参数转 po。
2. 提供粗粒度的方法,查询订单所有信息的方法。
3. 提供给 Controller 正常粒度的服务方法,根据需求,提供两个方法。1.从订单信息中获取订单价格等信息。 2.从订单信息中获取订单支付方式以及其他信息,并组装其他服务的信息,比如商品名,支付用户信息。

其他无关此无服务的方法,可以放到 Util 或者 Converter 中,比如调用其他微服务并处理内部调用异常的,以及 po 装 vo,vo 转 po,之类的。

参数的粒度

参数设计应该遵循迪米特法则。
在次引用一下

现在很多接口都是这样动不动就是一个 DO 或者 DTO 对象作为参数,但是到了实现一看,发现其实就是用到 DO/DTO 的两三个字段而已。这种大对象作为参数实际上是一种非常不好的作法,特别是如果你只用到了大数据对象的一小部分字段而已。举个例子大家就比较容易理解我为什么对它如此深恶痛绝了:在 com.alibaba.intl.biz.product.service.interfaces.ProductService 获取产品独立 detail 页面 URL 的接口定义如下:

com.alibaba.intl.biz.product.service.interfaces.ProductService
String getProductDetailUrl(URIBroker uriBroker, ProductSearchDTO product);

而在 com.alibaba.intl.biz.product.service.impl.ProductServiceImpl 中其实现只是用到了 ProductSearchDTO 的三个字段:getProductId(),getSubject(),getServiceType()。但是 ProductSearchDTO 这个类呢有十几个属性,并且还关联了一些 DO 对象。你说这样的一个接口给用户,它怎么知道应该填充这个 DTO 的那些字段呢?!这对内存空间也是一种浪费。 直接定义成这样的接口多简单: com.alibaba.intl.biz.product.service.interfaces.ProductService

String getProductDetailUrl(URIBroker uriBroker, Integer productId, String subject, ServiceType serviceType);

返回值的粒度

尽量用返回值而不是修改接口的引用参数,同时接口引用参数大部分情况下也不推荐。

内部接口的粒度

内部接口应尽量和 api 接口隔离开,尽量调用上面业务无关的方法,因为内部接口大部分情况下只需要根据外键来查询某个名字或者其他信息。

api 接口的粒度

每个 api 接口都应该有各自的 Request 和 Response 类,Request 和 Respone 类尽量不要复用,也不要考虑组合或者继承关系,一旦组合或者继承加了个限制,比如金额限制,时间限制,拿着就隐形的 bug。

单元测试粒度

controller 层只测试参数限制以及返回的内容格式等
service 只测试业务逻辑
mapper 只测试 sql 正确性

无关的 bean 一律用 mock 傻对象注入,参考:https://aoyouzi.iteye.com/blog/2343725

  • B3log

    B3log 是一个开源组织,名字来源于“Bulletin Board Blog”缩写,目标是将独立博客与论坛结合,形成一种新的网络社区体验,详细请看 B3log 构思。目前 B3log 已经开源了多款产品:SymSoloVditor思源笔记

    1090 引用 • 3467 回帖 • 297 关注
  • 软件工程
    29 引用 • 81 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...