场景
用户实体User
通过用户Id查找用户的订单信息接口
List<Order> orders = orderService.queryOrders(long userId)
通过用户Id查找用户退款订单Id列表
List<String> orderIds = orderRefundService.queryRefundOrderIds(long userId)
查找所有用户的信息
List<User> users = UserService.queryAllUsers()
要求查询用户订单消费总金额(除去退过款的订单)
实现
实现一
public List<User> queryUserStatistics(){
List<User> users = UserService.queryAllUsers()
for (User user : users) {
long userId = user.getAccountId();
List<Order> orders = orderService.queryOrderInfo();
BigDecimal totlePayAmount = filterRefundOrderAndCalculateAmount(orders,accountId);
user.setSumPayAmount(totlePayAmount);
}
}
private BigDecimal filterRefundOrderAndCalculateAmount(List<Order> orders, long userId) {
List<String> orderIds = orderRefundService.queryRefundOrderIds(userId);
BigDecimal totlePayAmount = BigDecimal.ZERO;
for (Order order : orders) {
if (!orderIds.contains(order.getOrderId())) {
totlePayAmount = totlePayAmount.add(order.getPayAmount());
}
}
return totlePayAmount;
}
实现二
public List<User> queryUserStatistics(){
List<User> users = UserService.queryAllUsers()
for(User user : users){
BigDecimal sumPayAmount = calculateTotleConsumeAmount(user);
user.setSumPayAmount(sumPayAmount);
}
}
private BigDecimal calculateTotleConsumeAmount(User user) {
long userId = user.getUserId();
List<Order> orders = orderService.queryOrderInfo(userId);
return filterRefundOrderAndCalculateAmount(orders, userId);
}
private BigDecimal filterRefundOrderAndCalculateAmount(List<Order> orders, long userId) {
List<String> orderIds = orderRefundService.queryRefundOrderIds(userId);
BigDecimal totlePayAmount = BigDecimal.ZERO;
for (Order order : orders) {
if (!orderIds.contains(order.getOrderId())) {
totlePayAmount = totlePayAmount.add(order.getPayAmount());
}
}
return totlePayAmount;
}
实现三
public List<User> queryUserStatistics(){
List<User> users = UserService.queryAllUsers()
for(User user : users){
BigDecimal sumPayAmount = calculateTotleConsumeAmount(user);
user.setSumPayAmount(sumPayAmount);
}
}
private BigDecimal calculateTotleConsumeAmount(User user) {
long userId = user.getUserId();
List<Order> orders = orderService.queryOrderInfo(userId);
List<String> orderIds = orderRefundService.queryRefundOrderIds(long userId);
return filterRefundOrderAndCalculateAmount(orderPayAmountVOs, orderIds);
}
private BigDecimal filterRefundOrderAndCalculateAmount(List<Order> orders,List<String> orderIds) {
BigDecimal is = BigDecimal.ZERO;
for (Order order : orders) {
if (!orderIds.contains(order.getOrderId())) {
totlePayAmount = totlePayAmount.add(order.getPayAmount());
}
}
return totlePayAmount;
}
实现结论
实现一:接到一个需求,完成工作,未仔细推敲代码的合理性
实现二:接到另外一个需求,需要复用实现一的部分代码,所以重新组织了下代码
实现三:仔细看了下实现二,觉得很别扭,深层次的思考了下代码的结构,发现实现二并没有满足现在已知需求的「抽象一致性」
说明
说明一
对于实现二queryUserStatistics()
的抽象层次,我们可以这样定义:
-
查找用户的订单消费总额和用户信息
查找用户信息
计算订单消费金额
-
计算订单消费金额
查找所有的订单信息
查找退款信息
过滤退款信息,计算消费金额
或查找所有的订单
过滤退款订单
计算消费金额
-
过滤退款订单
查找退款订单
过滤
结论一:实现二在已知的需求里面其实是不是非常满足「抽象一致性的」
结论二:仔细推敲下实现三,其实这个方法中filterRefundOrderAndCalculateAmount
还是不是非常满足「抽象一致性」的要求的。
说明二
从另外一个角度来看实现二
-
计算订单消费金额
查找所有的订单信息
过滤退款并计算消费金额
-
过滤退款并计算消费金额
查找退款信息
过滤退款信息
计算消费金额
结论一:如果这样子理解,也是可以说实现二也满足「抽象一致性」。
结论二:从不同的角度去看「抽象一致性」得出的结论是不一样的,只有最符合现有业务的,没有最正确的
说明三
对于实现一queryUserStatistics
方法是查询用户的消费信息,而这里的详细计算订单金额直接写在这个方法里面,抽象层次十分混乱,所以实现一是不推荐的。
总结
在编写代码的时候,尽量让方法或者类保持「抽象一致性」,这里说尽量的意思就是说明在很多时间可以违反这个约定(因为有的时候会觉得很没有必要,保持抽象一致性,就代表着你的方法里面可能需要很多私有方法,并且在极端情况下私有方法里面的代码数很少)
「抽象一致性」从不同的角度看,可能会有不同的结果,所以尽量选一个更加符合当前业务的角度(比如说实现一和实现二)
PS:关于抽象一致性更加详细的描述,可以翻看我以前的提问对抽象层次一致性的看法
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。