简介
本文简单介绍整洁代码中短函数的重要性,举例对比,望大家能在开发代码的过程当中,保持代码的整洁度,避免成为“公司不可或缺”的程序员。
短函数
一个函数的代码量不要过长,短函数更易读,易维护,易测。
举一个真实的开发环境中的例子:根据入参查询账户表的信息。
public Page queryAccountList(QueryAccountListReq params) {
//构建MybatisPlus的Sql入参实体
Wrapper<Account> wrapper = new EntityWrapper<>();
if (StringUtils.isNotBlank(params.getName()) {
wrapper.eq("name", params.getName());
}
if (Objects.nonNull(params.getId) && params.getId() > 0) {
wrapper.eq("id", params.getId());
}
if (CollectionUtils.isNotEmpty(params.getStatusList()) {
wrapper.in(CollectionUtils.isNotEmpty(params.getStatusList()), "status", params.getStatusList());
}
if (StringUtils.isNotBlank(params.getAbility())) {
wrapper.eq("ability", params.getAbility());
}
wrapper.orderBy("create_time", false);
Page page = new Page(params.getPageIndex(), params.getPageSize());
//查表
List<Account> accountList = accountMapper.selectPage(page.toPagination(), wrapper);
log.info("查询账户列表接口返回结果:{}", GsonUtil.toJSONString(accountList));
if (CollectionUtils.isEmpty(accountList)) {
return new Page();
}
//构建返回结果列表
List<AccountVO> accountVOList = new ArrayList<>();
accountList.forEach(account -> {
AccountVO accountVO = new AccountVO();
BeanUtils.copyProperties(account, accountVO));
accountVO.setShowTime(account.getCreateTime());
accountVOList.add(accountVo);
});
page.setRecords(accountVOList);
log.info("查询账户列表最终返回结果:{}", GsonUtil.toJSONString(page));
return page;
}
虽然代码行数只有三四十行,逻辑也很简单,但是代码没有明显的层次感。
我们按照代码功能,把代码拆分成多个函数。
优化后:
public Page queryAccountList(QueryAccountListReq params) {
Wrapper<Account> wrapper = buildQueryListWrapper(params);
Page page = new Page(params.getPageIndex(), params.getPageSize());
List<Account> accountList = accountMapper.selectPage(page.toPagination(), wrapper);
log.info("查询账户列表接口返回结果:{}", GsonUtil.toJSONString(accountList));
buildResultToPage(accountList, page);
return page;
}
public Wrapper<Account> buildQueryListWrapper(QueryAccountListReq params) {
Wrapper<Account> wrapper = new EntityWrapper<>();
wrapper.eq(StringUtils.isNotBlank(params.getName()), "name", params.getName())
.eq(idIsNotNull(params.getId()), "id", params.getAuthId())
.eq(StringUtils,isNotBlank(params.getAbility(), "ability", params.getAbility())
.in(CollectionUtils.isNotEmpty(params.getStatusList()), "status", params.getStatusList())
.orderBy("create_time", false);
return wrapper;
}
public boolean idIsNotNull (Integer id) {
return Objects.nonNull(id) && id > 0;
}
public void buildResultToPage (List<Account> accountList, Page page) {
page.setRecords(buildAccountVOList(accountList));
log.info("查询账户列表最终返回结果:{}", GsonUtil.toJSONString(page));
}
public List<AccountVO> buildAccountVOList (List<Account> accountList) {
if (CollectionUtils.isEmpty(accountList)) {
return Collections.emptyList();
}
List<AccountVO> accountVOList = new ArrayList<>();
accountList.forEach(account -> {
AccountVO accountVO = new AccountVO();
BeanUtils.copyProperties(account, accountVO));
accountVO.setShowTime(account.getCreateTime());
accountVOList.add(accountVo);
});
return accountList;
}
优化后与优化之前相比:
1.代码的写单测的难度明显降低。
例如:你在写buildResultToPage的单测代码的时候,优化之前的代码,需要mock出
accountMapper.selectPage的结果,现在你只需要在入参中构建出你的结果即可。
2.代码的可读性明显提高。
优化后的queryAccountList函数的主要内容大体分为三步:
第一步就是构建MybatisPlus的sql参数实体。
第二步调用DAO查询出表中的结果。
第三部构建最终需要用到的数据。
3.代码的可维护性明显提高
例如步骤2中说到的queryAccountList函数的三个步骤。
如果后续需求迭代中需要新增一个查询条件,那么我们只需要在 buildQueryListWrapper函数中
构建一个我们需要新增的参数,如果结果集的数据有修改,我们只需要在 buildResultToPage
函数中,按照我们的诉求修改代码即可。