当前位置:网站首页>如何优雅的消除系统重复代码
如何优雅的消除系统重复代码
2022-08-01 23:55:00 【InfoQ】
引言
为什么要消除重复代码
系统维护成本高
程序Bug概率高
如何优雅的消除重复代码
统一参数校验
public OrderDTO queryOrderById(String id) {
if(StringUtils.isEmpty(id)) {
return null;
}
OrderDTO order = orderBizService.queryOrder(id);
if(Objects.isNull(Order)) {
return null;
}
...
}
public List<UserDTO> queryUsersByType(List<String> type) {
if(StringUtils.isEmpty(id)) {
return null;
}
...
}
public class Assert {
public static void notEmpty(String param) {
if(StringUtils.isEmpty(param)) {
throw new BizException(ErrorCodes.PARAMETER_IS_NULL, "param is empty or null");
}
}
public static void notNull(Object o) {
if (Objects.isNull(o)) {
throw new BizException(ErrorCodes.PARAMETER_IS_NULL, "object is null");
}
}
public static void notEmpty(Collection collection) {
if(CollectionUtils.isEmpty(collection)) {
throw new BizException(ErrorCodes.PARAMETER_IS_NULL, "collection is empty or null");
}
}
}
public OrderDTO queryOrderById(String id) {
Assert.notEmpty(id);
OrderDTO order = orderBizService.queryOrder(id);
Assert.notNull(order);
...
}
public List<UserDTO> queryUsersByType(List<String> type) {
Assert.notEmpty(type);
...
}
统一异常处理
@GetMapping("list")
public ResponseResult<OrderVO> getOrderList(@RequestParam("id")String userId) {
try {
OrderVO orderVo = orderBizService.queryOrder(userId);
return ResponseResultBuilder.buildSuccessResponese(orderDTO);
} catch (BizException be) {
// 捕捉业务异常
return ResponseResultBuilder.buildErrorResponse(be.getCode, be.getMessage());
} catch (Exception e) {
// 捕捉兜底异常
return ResponseResultBuilder.buildErrorResponse(e.getMessage());
}
}
@ControllerAdvice
@ResponseBody
public class UnifiedException {
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(BizException.class)
@ResponseBody
public ResponseResult handlerBizException(BizException bizexception) {
return ResponseResultBuilder.buildErrorResponseResult(bizexception.getCode(), bizexception.getMessage());
}
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult handlerException(Exception ex) {
return ResponseResultBuilder.buildErrorResponseResult(ex.getMessage());
}
}
@GetMapping("list")
public ResponseResult<OrderVO> getOrderList(@RequestParam("id")String userId) {
List<OrderVO> orderVo = orderBizService.queryOrder(userId);
return ResponseResultBuilder.buildSuccessResponese(orderVo);
}
优雅的属性拷贝
public class TaskConverter {
public static TaskDTO taskModel2DTO(TaskModel taskModel) {
TaskDTO taskDTO = new TaskDTO();
taskDTO.setId(taskModel.getId());
taskDTO.setName(taskModel.getName());
taskDTO.setType(taskModel.getType());
taskDTO.setContent(taskModel.getContent());
taskDTO.setStartTime(taskModel.getStartTime());
taskDTO.setEndTime(taskModel.getEndTime());
return taskDTO;
}
}
public class TaskConverter {
public static TaskDTO taskModel2DTO(TaskModel taskModel) {
TaskDTO taskDTO = new TaskDTO();
BeanUtils.copyProperties(taskModel, taskDTO);
return taskDTO;
}
}
核心能力抽象
public Class NormalUserSettlement {
//省略代码
...
public Bigdecimal calculate(String userId) {
//计算商品总价格
List<Goods> goods = shoppingService.queryGoodsById(userId);
Bigdecimal total = goods.stream().map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getAmount()))).reduce(BigDecimal.ZERO, BigDecimal::add);
//计算优惠
Bigdecimal discount = total.multiply(new Bigdecimal(0.1));
//计算应付金额
Bigdecimal payPrice = total - dicount;
return payPrice;
}
//省略代码
...
}
public Class VIPUserSettlement {
//省略代码
...
public Bigdecimal calculate(String userId) {
//计算商品总价格
List<Goods> goods = shoppingService.queryGoodsById(userId);
Bigdecimal total = goods.stream().map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getAmount()))).reduce(BigDecimal.ZERO, BigDecimal::add);
//计算优惠
Bigdecimal discount = total.multiply(new Bigdecimal(0.2));
//计算应付金额
Bigdecimal payPrice = total - dicount;
return payPrice;
}
//省略代码
...
}
public Class VIPUserSettlement {
//省略代码
...
public Bigdecimal calculate(String userId) {
//计算商品总价格
List<Goods> goods = shoppingService.queryGoodsById(userId);
Bigdecimal total = goods.stream().map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getAmount()))).reduce(BigDecimal.ZERO, BigDecimal::add);
//计算优惠
Bigdecimal discount = total.multiply(new Bigdecimal(0.2));
//计算应付金额
Bigdecimal payPrice = total - dicount;
return payPrice;
}
//省略代码
...
}
public Class AbstractSettlement {
//省略代码
...
public abstact Bigdecimal calculateDiscount();
public Bigdecimal calculate(String userId) {
//计算商品总价格
List<Goods> goods = shoppingService.queryGoodsById(userId);
Bigdecimal total = goods.stream().map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getAmount()))).reduce(BigDecimal.ZERO, BigDecimal::add);
//计算优惠
Bigdecimal discount = calculateDiscount();
//计算应付金额
Bigdecimal payPrice = total - dicount;
return payPrice;
}
//省略代码
...
}

自定义注解和AOP
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeCost {
}
@Aspect
@Component
public class CostTimeAspect {
@Pointcut(value = "@annotation(com.mufeng.eshop.anotation.CostTime)")
public void costTime(){ }
@Around("runTime()")
public Object costTimeAround(ProceedingJoinPoint joinPoint) {
Object obj = null;
try {
long beginTime = System.currentTimeMillis();
obj = joinPoint.proceed();
//获取方法名称
String method = joinPoint.getSignature().getName();
//获取类名称
String class = joinPoint.getSignature().getDeclaringTypeName();
//计算耗时
long cost = System.currentTimeMillis() - beginTime;
log.info("类:[{}],方法:[{}] 接口耗时:[{}]", class, method, cost + "毫秒");
} catch (Throwable throwable) {
throwable.printStackTrace();
}
return obj;
}
}
@GetMapping("/list")
public ResponseResult<List<OrderVO>> getOrderList(@RequestParam("id")String userId) {
long beginTime = System.currentTimeMillis();
List<OrderVO> orderVo = orderBizService.queryOrder(userId);
log.info("getOrderList耗时:" + System.currentTimeMillis() - beginTime + "毫秒");
return ResponseResultBuilder.buildSuccessResponese(orderVo);
}
@GetMapping("/item")
public ResponseResult<OrderVO> getOrderById(@RequestParam("id")String orderId) {
long beginTime = System.currentTimeMillis();
OrderVO orderVo = orderBizService.queryOrderById(orderId);
log.info("getOrderById耗时:" + System.currentTimeMillis() - beginTime + "毫秒");
return ResponseResultBuilder.buildSuccessResponese(orderVo);
}
@GetMapping("/list")
@TimeCost
public ResponseResult<List<OrderVO>> getOrderList(@RequestParam("id")String userId) {
List<OrderVO> orderVo = orderBizService.queryOrder(userId);
return ResponseResultBuilder.buildSuccessResponese(orderVo);
}
@GetMapping("/item")
@TimeCost
public ResponseResult<OrderVO> getOrderList(@RequestParam("id")String orderId) {
OrderVO orderVo = orderBizService.queryOrderById(orderId);
return ResponseResultBuilder.buildSuccessResponese(orderVo);
}
引入规则引擎

public double calculate(int profit) {
if(profit < 1000) {
return profit * 0.1;
} else if(1000 < profit && profit< 2000) {
return profit * 0.15;
} else if(2000 < profit && profit < 3000) {
return profit * 0.2;
}
return profit * 0.3;
}
// 奖励规则
package reward.rule
import com.mufeng.eshop.biz.Reward
// rule1:如果利润小于1000,则奖励计算规则为profit*0.1
rule "reward_rule_1"
when
$reward: Reward(profit < 1000)
then
$reward.setReward($reward.getProfit() * 0.1);
System.out.println("匹配规则1,奖励为利润的1成");
end
// rule2:如果利润大于1000小于2000,则奖励计算规则为profit*0.15
rule "reward_rule_2"
when
$reward: Reward(profit >= 1000 && profit < 2000)
then
$reward.setReward($reward.getProfit() * 0.15);
System.out.println("匹配规则2,奖励为利润的1.5成");
end
// rule3:如果利润大于2000小于3000,则奖励计算规则为profit*0.2
rule "reward_rule_3"
when
$order: Order(profit >= 2000 && profit < 3000)
then
$reward.setReward($reward.getProfit() * 0.2);
System.out.println("匹配规则3,奖励为利润的2成");
end
// rule4:如果利润大于等于3000,则奖励计算规则为profit*0.3
rule "reward_rule_4"
when
$order: Order(profit >= 3000)
then
$reward.setReward($reward.getProfit() * 0.3);
System.out.println("匹配规则4,奖励为利润的3成");
end
public class DroolsEngine {
private KieHelper kieHelper;
public DroolsEngine() {
this.kieHelper = new KieHelper();
}
public void executeRule(String rule, Object unit, boolean clear) {
kieHelper.addContent(rule, ResourceType.DRL);
KieSession kieSession = kieHelper.getKieContainer().newKieSession();
//插入判断实体
kieSession.insert(unit);
//执行规则
kieSession.fireAllRules();
if (clear) {
kieSession.dispose();
}
}
}
public class Profit {
public double calculateReward(Reward reward) {
String rule = "classpath:rules/reward.drl";
File rewardFile = new File(rule);
String rewardDrl = FileUtils.readFile(rewardFile, "utf-8");
DroolsEngine engine = new DroolsEngine();
engine.executeRule(rewardDrl, reward, true);
return reward.getReward();
}
}
消除重复代码方法论


总结
边栏推荐
- windows sql server 如何卸载干净?
- 几道关于golang并发的面试题
- oozie startup error on cdh's hue, Cannot allocate containers as requested resource is greater than maximum allowed
- Share an interface test project (very worth practicing)
- How to get the best power efficiency in Windows 11?
- 12306抢票,极限并发带来的思考?
- 分享一份接口测试项目(非常值得练手)
- numpy.around
- 洞见云原生微服务及微服务架构浅析
- 正则表达式
猜你喜欢
cdh6 opens oozieWeb page, Oozie web console is disabled.
WEB安全基础 - - - XRAY使用
OpenCV DNN blogFromImage()详解
[Camp Experience Post] 2022 Cybersecurity Summer Camp
Excel表格数据导入MySQL数据库
Dynamic Scene Deblurring with Parameter Selective Sharing and Nested Skip Connections
Excel导入和导出
Deep Learning Fundamentals - Numpy-based Recurrent Neural Network (RNN) implementation and backpropagation training
Artifact XXXwar exploded Artifact is being deployed, please wait...(已解决)
软件测试之移动APP安全测试简析,北京第三方软件检测机构分享
随机推荐
Data Organization --- Chapter 5 Trees and Binary Trees --- The Concept of Binary Trees --- Application Questions
GIF制作-灰常简单的一键动图工具
【Leetcode】473. Matchsticks to Square
Excel文件读写(创建与解析)
Docker搭建Mysql主从复制
security跨域配置
What can be done to make this SQL into a dangerous SQL?
使用Ganache、web3.js和remix在私有链上部署并调用合约
Flink Yarn Per Job - Yarn应用
An interview question about iota in golang
color transparency parameter
Flink学习第五天——Flink可视化控制台依赖配置和界面介绍
分享一份接口测试项目(非常值得练手)
【Leetcode】470. Implement Rand10() Using Rand7()
EasyExcel的简单读取操作
【MySQL系列】 MySQL表的增删改查(进阶)
Docker实践经验:Docker 上部署 mysql8 主从复制
asyncawait和promise的区别
@Scheduled注解详解
numpy.unique