buguge - Keep it simple,stupid

知识就是力量,但更重要的,是运用知识的能力why buguge?

导航

代码易读性实践

🍀 I care about details like this.

下面6行代码,是在给一个转账对象进行赋值操作,其中包括3个转出账户的属性,和3个转入账户的属性。在易读性方面,需要做一个调整,你看出来了吗?

transferOrder.setOutMerId(**);
transferOrder.setOutMerName(**);
transferOrder.setOutAccountId(**);
transferOrder.setInMerId(**);
transferOrder.setInAccountId(**);
transferOrder.setInMerName(**);

如果没有看出来,不妨自己手撸一下,在你的IDE里写出来这6行。比较一下,就知道了。如果还没有,很抱歉,我想我没办法了!



🍀🍀 NoCache是“不走缓存”?

我在DAO里定义了一个方法,selectByAccountNoCache 这个方法的含义是 通过accountNo查询数据,会走缓存。

但是理解起来, 可能会把其中的 NoCache 理解为”不走缓存“。 请问怎么重命名这个方法呢?

DeepSeek: 查询数据涉及到读缓存时,可以在方法名中加入缓存相关的词汇,比如Cache、Cached、WithCache等,可以明确表达方法使用了缓存。同时,需要避免使用可能引起歧义的词汇,比如本案例中的“No”,本意是表示“序号”(Number),但与“Cache”结合一起,NoCache,容易让人产生负面联想为“不走缓存”/“没有缓存”。

根据方法的实际功能(查询时走缓存),建议以下更清晰的命名方案:

推荐方案

原方法名 问题分析 推荐新方法名 命名逻辑说明
selectByAccountNoCache "NoCache" 易误解为「不缓存」 selectByAccountWithCache WithCache 明确表示「带缓存」
findByAccountNoCached Cached 强调结果来自缓存
getByAccountNoUsingCache UsingCache 表明缓存是查询过程的一部分
getByAccountNo_Cache 下划线分隔,可能不符合方法命名规范,但彻底规避理解歧义


🍀🍀🍀 领域驱动设计

我们着手开发一个新的优惠券系统,这个系统主要涉及到两类企业,其中,一类企业(PRD称为“企业”)是申请优惠券的一方,另一类企业(PRD称为“核销企业”)是优惠券核销方。

”核销企业“通过运营系统录入的方式,进入优惠券系统(又称“入网”)。 ”企业“通过自主注册”核销企业“API报送的方式,进入优惠券系统里。

关于入网,这两类企业包括相同的数据,如登录口令、企业资质、法人证件、联系人。

在设计表时,一个开发者主张为这2类企业创建一个相同的表,来存储他们的信息。

我持不同意见!

理由是,从系统参与方来看,这两类企业是不同的,它们参与的业务、业务环节也不同,因此,有必要为这两类企业创建不同的entity。这样,后面的业务表里,才更容易识别两类企业的“身份”

具体实现层面,首先,我们声明系统的数据词典, 约定”企业“为enterprise,约定“核销企业”为levy。创建两张表,t_enterprise、t_levy,用来存储这2类企业的特定信息,同时,考虑将企业资质、法人证件等同类数据放到一个 t_parter_ext_info表中。这样,应用程序里,会有对应的EnterpriseLevy 这2个entity。

相反,如果为这两类企业创建一个相同的表,即,让这两类企业使用同一种entity。那么,可以想象,系统将会变得不易读、不易理解、不易维护。



🍀🍀🍀🍀 方法重载的艺术

我们在为我们的商户API开发一个SDK,以方便合作商户快速进行API对接。

API接口的请求体结构 LevyRequestBase 见下方定义:

@Data
public class LevyRequestBase {
    private String merId;
    private FunCodeEnum funCode;
    private String version;
    private String reqId;// 请求唯一ID
    private String sign;

    private String reqData;// 请求数据(加密后的密文)
}

开发者在编写一个通用的API请求方法,用来封装 LevyRequestBase 的构建、数据的加密加签、http请求、响应数据的验签解密。

public static <ReqData> LevyResponseBase doBusiness(FunCodeEnum funCode, ReqData requestData) {
    ...
}

所存在的一个情况是,在这些API中,多数接口需要为 reqData指定请求数据,诸如 商户信息上报接口、商户充值接口,还有一少部分接口,诸如查询商户余额、查询商户基础信息的接口,不需要 reqData。

为此,开发者定义了一个 EmptyRequest,顾名思义,是一个没有任何field的结构体,public class EmptyRequest { }。用来让调用者程序来使用它。

其实,大可以不用如此。也许,下面这样的方法重载,更合适。

/**
 * 请求接口,与{@link #doBusiness(FunCodeEnum, Object)}所不同的是,此方法针对那些不需要传输请求数据的接口请求。例如,获取商户余额。
 */
public static <ReqData> LevyResponseBase doBusiness(FunCodeEnum funCode) {
    return doBusiness(funCode, new Object());
}
/**
* 请求接口。如果不需要传输请求数据的接口请求,可指定第二个参数为null,或使用{@link #doBusiness(FunCodeEnum)}
*/
public static <ReqData> LevyResponseBase doBusiness(FunCodeEnum funCode, ReqData requestData) {
    ...
}

🍀🍀🍀🍀🍀 I care about details like this.

代码易读性实践

🍀🍀🍀🍀🍀🍀 如何调整package显示顺序

一个package中有如下子包。 我想让route这个包显示在第一位,有什么好办法?

dx
dxnew
ge
gsb
htzyh
huiqi
jrmf
js
jxfy
lxf
own
pdx
route
sanhe
sanhe202507
sp

可考虑添加前缀的方式。重命名 route包,在前面加一个下划线或字母前缀:例如 _routea_route。这个方案比较不错,因为:
•最简单有效
•IDEA可手动调整包显示顺序,但IDEA重启后可能会丢失
•不影响实际代码结构
•其他开发者看到也能理解你的意图

这样修改后,这些子包列表会显示为:

_route
dx
dxnew
ge
...

🍀🍀🍀🍀🍀🍀🍀

posted on 2025-05-20 11:26  buguge  阅读(27)  评论(0)    收藏  举报