本文正在参加「Java主题月 - Java Debug笔记活动」,详情查看 活动链接
初衷
作为一个合格的开发, 除了在保证代码有效性的前提. 我们需要在其它方面来提供代码的质量. 自己总结了一些,优化代码的方面有以下几种:
-
抽取重复代码超过5行以上的代码. 在idea中简单的抽取可以使用快捷键
Ctrl + Alt + M
键. 如果代码复用性不仅仅存在于当前类中,可以将改方法抽象化或者提取的util
工具包中 -
避免直接使用字符串当作参数或者变量使用, 将魔法值提取到 单体的类中进行整体维护
-
在有必要的情况下,创建枚举类对一些关键字或者页面特殊数字字段状态的维护
-
使用断言精简代码
-
使用
lambda
表达式精简代码
在后面我会贴出一些自认为毕竟简洁使用的代码
Assert 断言
查看源码不难看出,每个方法具体代表什么含义
断言的主要使用场景在于字段校验
这里先举几个常用的.
空值校验
Assert.isNull(obj, "返回的错误检验规则提示")
obj
不是空的时候触发Assert.notNull(obj,"为空值的时候触发")
布尔校验
Assert.isTrue(boolean, "错误日志返回")
表达式校验
Assert.state(boolean,"与isTrue基本相同用法")
异常日志返回封住
自定义断言
public class Assert {
public static T fail(String message) {
throw new ApiException(message);
}
public static T fail(RetCode retCode){
throw new ApiException(retCode);
}
}
异常封装
public class ApiException extends RuntimeException
{
private IErrorCode errorCode;
public ApiException(IErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
public ApiException(String message) {
super(message);
}
public ApiException(Throwable cause) {
super(cause);
}
public ApiException(String message, Throwable cause) {
super(message, cause);
}
public IErrorCode getErrorCode() {
return errorCode;
}
}
时间代码中的使用
常用获取集合某字段的封装
封装的原因: 实际中有很多字段一些状态,枚举等都会存放在数据字典中,用户的名称,单位,角色,机构等都会单独存在自己的业务表中.随着服务的规模越来越大.需要将这种通过ids
查询实际含义的接口得单处出来 .每次列表页面数据翻译,多次重复使用lambda
表达式,代码重复度较高.这里才有二次封装的形式.
这里贴一些代码优化前后的区别: 优化前的代码
//获取userIds
String userIds = list.stream()
.map(RepairVo::getUserId)
.map(String::valueOf)
.collect(Collectors.joining(","));
//获取orgIds
String orgIds = list.stream()
.map(RepairVo::getOrgId)
.map(String::valueOf)
.collect(Collectors.joining(","));
// 获取字典项目
String dictIds = list.stream()
.map(RepairVo::getType)
.map(String::valueOf)
.collect(Collectors.joining(","));
// 然后通过单独的服务 分别查询userName orgNames dictNames 再赋值
优化之后的代码
Map<Integer, String> orgNames = CommonUtils.getOrgChainNames(organizationService, list, RepairVo::getOrgId);
Map<Integer, String> usernames = CommonUtils.getUsernames(userService, list, RepairVo::getApplicant, RepairVo::getCurrentUserId);
Map<Integer, String> dictNames = CommonUtils.getOrgChainNames(dictService, list, RepairVo::getType);
//翻译后的值回填
return list.stream()
.map(e -> new RepairVo(e, orgNames, usernames,dictNames))
.collect(Collectors.toList());
RepairVo
实体类
@Data
public class RepairVo {
private Integer id;
private Integer userId;
private String username;
private Integer type;
private String typeName;
private String code;
private Integer orgId;
private String orgName;
public RepairVo(RepairVo vo,Map<Integer, String> orgNames, Map<Integer, String> usernames,Map<Integer, String> dictNames {
BeanUtils.copyProperties(vo, this);
setUsername(usernames.get(vo.getUserId());
setOrgName(orgNames.get(vo.getOrgId());
setTypeName(dictNames.get(vo.getType());
}
}
封装的工具类
public class CommonUtils {
public static void badRequest(String errorCode, String entityName) {
throw badReq(errorCode, entityName);
}
public static BadRequestAlertException badReq(String errorCode, String entityName) {
return new BadRequestAlertException(errorCode, entityName, errorCode);
}
public static Instant toInstant(String datetime) {
return LocalDateTime.parse(datetime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).toInstant(ZoneOffset.ofHours(8));
}
public static <T> PageDTO<T> transfer(Page<T> page) {
return createPage(page.getContent(), page.getTotalElements());
}
public static <T> PageDTO<T> createPage(List<T> list, long total) {
PageDTO<T> p = new PageDTO<>();
p.setItems(list);
p.setTotal(new Long(total).intValue());
return p;
}
public static Map<String, Object> getResponse(Long id) {
Map<String, Object> res = new HashMap<>();
res.put("id", id);
return res;
}
@SafeVarargs
public static <E, M> List<String> map(Collection<E> entries, Function<E, M>... getters) {
if (CollectionUtils.isEmpty(entries)) {
return Collections.emptyList();
}
Assert.notEmpty(getters, "At least 1 elements in the \"getters\" parameter");
List<M> values = new ArrayList<>();
entries.forEach(e -> Stream.of(getters).map(getter -> getter.apply(e)).forEach(values::add));
return values.parallelStream().filter(Objects::nonNull).distinct().map(Objects::toString).collect(Collectors.toList());
}
@SafeVarargs
public static <E, M> String groupConcat(Collection<E> entries, String delimiter, boolean quote, Function<E, M>... getters) {
return map(entries, getters)
.parallelStream()
.map(s -> quote ? StringUtils.quote(s) : s)
.collect(Collectors.joining(delimiter));
}
@SafeVarargs
public static <E, M> String groupConcat(Collection<E> entries, boolean quote, Function<E, M>... getters) {
return groupConcat(entries, ",", quote, getters);
}
@SafeVarargs
public static <E, M> String groupConcat(Collection<E> entries, Function<E, M>... getters) {
return groupConcat(entries, false, getters);
}
@SafeVarargs
public static <E, M> Map<Integer, String> getUsernames(UserService service, Collection<E> entries, Function<E, M>... getters) {
String userIds = groupConcat(entries, getters);
return StringUtils.isEmpty(userIds) ? Collections.emptyMap() : service.getUserNamesByUserIds(userIds);
}
@SafeVarargs
public static <E, M> Map<Integer, String> getOrgNames(OrganizationService service, Collection<E> entries, Function<E, M>... getters) {
String orgIds = groupConcat(entries, getters);
return StringUtils.isEmpty(orgIds) ? Collections.emptyMap() : service.getOrgNamesByOrgIds(orgIds);
}
@SafeVarargs
public static <E, M> Map<Integer, String> getOrgChainNames(OrganizationService service, Collection<E> entries, Function<E, M>... getters) {
String orgIds = groupConcat(entries, getters);
return StringUtils.isEmpty(orgIds) ? Collections.emptyMap() : service.getChainNamesByIds(orgIds);
}
@SafeVarargs
public static <E, M> Map<Integer, String> getDictNames(DictService dictService, Collection<E> entries, Function<E, M>... getters) {
String ids = groupConcat(entries, getters);
return StringUtils.isEmpty(ids) ? Collections.emptyMap() : dictService.getDictNamesByIds(ids);
}
}