
在java开发中,随着业务逻辑的增长和复杂化,我们常常会遇到深层嵌套的`if-else`语句,俗称“if-else地狱”。这种结构不仅使得代码难以阅读和理解,还增加了维护成本和引入bug的风险。尤其当条件判断依赖于多个动态输入时,代码的混乱程度会急剧上升。本文将介绍如何通过方法提取和卫语句(guard clauses)等重构技巧,将复杂的条件逻辑转化为清晰、模块化且易于管理的代码。
当业务规则涉及多个对象的状态检查和多层条件判断时,if-else语句很容易变得冗长且嵌套。例如,在处理商品定价逻辑时,可能需要检查订单详情、商品信息、用户来源、供应商策略等多个因素。原始代码示例如下:
if (orderDetail != null && item != null && !orderDetail.isUnitPriceModified()) {
ItemSizeColorStyle itemSizeColorStyle = itemSizeColorStyleRepository.findByRecordID(orderDetail.getItemSCSID());
if (origin != null && (origin.contains("b2baccess") || (origin.contains(".myappdev") && !origin.contains("apps.myappdev")))) {
RepGroupManufacturer repGroupManufacturer = repGroupManufacturerRepository.findByRepGroupIDAndManufacturerIDAndRecordDeleted(repGroupID, manufacturerID, NOT_DELETED);
if (repGroupManufacturer != null && repGroupManufacturer.getB2bItemPricingPolicy() != null && repGroupManufacturer.getB2bItemPricingPolicy().equalsIgnoreCase(ReptimeConstants.SHOWRETAILPRICE)) {
if (orderDetail.getItemSCSID() == null && item.getRetailPrice() != null) {
orderDetail.setUnitPrice(item.getRetailPrice());
} else {
if (itemSizeColorStyle != null && itemSizeColorStyle.getRetailPrice() != null) {
orderDetail.setUnitPrice(itemSizeColorStyle.getRetailPrice());
} else if (itemSizeColorStyle != null && itemSizeColorStyle.getRetailPrice() == null && item.getRetailPrice() != null) {
orderDetail.setUnitPrice(item.getRetailPrice());
} else if (itemSizeColorStyle != null && itemSizeColorStyle.getRetailPrice() == null && item.getRetailPrice() == null) {
throw new NullPointerException("item price can not be null.");
}
}
}
}
}这段代码存在以下问题:
为了解决上述问题,我们可以采用以下两种核心重构策略:
我们将上述复杂的定价逻辑重构为两个更小、更专注的方法:setUnitPrice 和 getUnitPrice。
立即学习“Java免费学习笔记(深入)”;
setUnitPrice 方法负责协调整个定价过程,并处理一些高级别的验证。它使用卫语句来快速排除不满足基本条件的场景,避免了深层嵌套。
public static void setUnitPrice(OrderDetail orderDetail, String origin) {
// 卫语句:检查基本参数和订单状态
if (orderDetail == null || item == null || orderDetail.isUnitPriceModified()) {
return; // 不满足条件,直接返回
}
// 卫语句:检查来源条件
// 注意:原始条件 `!origin.contains("b2baccess") || !origin.contains(".myappdev") && origin.contains("apps.myappdev")`
// 逻辑可能需要根据实际业务调整,这里假设其意图是排除某些特定来源。
// 如果原始意图是 `origin.contains("b2baccess") || (origin.contains(".myappdev") && !origin.contains("apps.myappdev"))`
// 那么卫语句应该是 `!(origin.contains("b2baccess") || (origin.contains(".myappdev") && !origin.contains("apps.myappdev")))`
// 为了简化和演示卫语句,我们假设一个简单的排除逻辑。
if (origin == null || !(origin.contains("b2baccess") || (origin.contains(".myappdev") && !origin.contains("apps.myappdev")))) {
return;
}
// 查询RepGroupManufacturer
RepGroupManufacturer repGroupManufacturer = repGroupManufacturerRepository
.findByRepGroupIDAndManufacturerIDAndRecordDeleted(repGroupID, manufacturerID, NOT_DELETED);
// 卫语句:检查制造商策略
if (repGroupManufacturer == null ||
repGroupManufacturer.getB2bItemPricingPolicy() == null ||
!repGroupManufacturer.getB2bItemPricingPolicy().equalsIgnoreCase(ReptimeConstants.SHOWRETAILPRICE)) {
return;
}
// 查询ItemSizeColorStyle
ItemSizeColorStyle itemSizeColorStyle = itemSizeColorStyleRepository.findByRecordID(orderDetail.getItemSCSID());
// 调用辅助方法获取最终单价
orderDetail.setUnitPrice(getUnitPrice(itemSizeColorStyle, item, orderDetail));
}getUnitPrice 方法的职责是根据 ItemSizeColorStyle 和 Item 信息来确定最终的单价。它也大量使用了卫语句来处理不同的定价逻辑分支。
public static Integer getUnitPrice(ItemSizeColorStyle itemSizeColorStyle, Item item, OrderDetail orderDetail) {
// 卫语句:如果ItemSCSID为空且商品有零售价,则使用商品的零售价
if (orderDetail.getItemSCSID() == null && item.getRetailPrice() != null) {
return item.getRetailPrice();
}
// 卫语句:如果ItemSizeColorStyle有零售价,则使用其零售价
if (itemSizeColorStyle != null && itemSizeColorStyle.getRetailPrice() != null) {
return itemSizeColorStyle.getRetailPrice();
}
// 卫语句:如果ItemSizeColorStyle无零售价但商品有零售价,则使用商品的零售价
if (itemSizeColorStyle != null && itemSizeColorStyle.getRetailPrice() == null && item.getRetailPrice() != null) {
return item.getRetailPrice();
}
// 所有条件都不满足,且无法确定价格,抛出异常
throw new NullPointerException("item price can not be null.");
}注意:getUnitPrice 返回类型为 Integer 假设价格可以是 null 或一个整数。如果价格必须是非负整数,可以考虑返回 int 并使用 Optional<Integer> 来表示可能缺失的价格,或者在调用处处理 null。
通过方法提取和卫语句的运用,重构后的代码具有以下显著优势:
虽然本例主要通过方法提取和卫语句来优化条件逻辑,但对于某些特定场景,Map 也可以用于重构if-else。Map 通常适用于根据一个明确的“键”来执行不同的“动作”或获取不同的“值”的场景,例如:
然而,对于本例中这种涉及复杂、顺序依赖的条件判断链,Map 并不总是最直接或最优雅的解决方案。本例的条件判断更像是决策树,而不是简单的键值映射。因此,方法提取和卫语句是更合适的选择。
复杂的if-else结构是代码异味的一种常见表现。通过运用方法提取和卫语句等重构技术,我们可以有效地将混乱的条件逻辑转化为清晰、模块化且易于维护的代码。这不仅提升了代码的可读性和可测试性,也为项目的长期健康发展奠定了基础。在日常开发中,应当时刻警惕深层嵌套的if-else,并积极寻找机会对其进行优化。
以上就是Java中重构复杂if-else语句:使用卫语句和方法提取提升代码可读性的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号