如何简化复杂的业务"IF"逻辑?

Zel*_*lid 14 refactoring business-logic

处理复杂业务逻辑的好方法是什么,从一开始就需要许多嵌套的if语句?

例:

优惠券.可能:

1a)价值折扣
1b)百分比折扣

2a)正常折扣
2b)累进折扣

3a)需要访问优惠券
3b)不需要访问优惠券

4a)仅适用于已经购买的客户
4b)适用于任何客户

5a)仅从国家(X,Y,...)应用于客户

这要求代码更复杂,然后:

if (discount.isPercentage) {
    if (discount.isNormal) {
        if (discount.requiresAccessCoupon) {
        } else {
        }
    } else if (discount.isProgressive) {
        if (discount.requiresAccessCoupon) {
        } else {
        }
    }
} else if (discount.isValue) {
    if (discount.isNormal) {
        if (discount.requiresAccessCoupon) {
        } else {
        }
    } else if (discount.isProgressive) {
        if (discount.requiresAccessCoupon) {
        } else {
        }
    }
} else if (discount.isXXX) {
    if (discount.isNormal) {
    } else if (discount.isProgressive) {
    }
}
Run Code Online (Sandbox Code Playgroud)

即使您将IF替换为开关/外壳,它仍然太复杂.有哪些方法可以使其可读,可维护,更易测试且易于理解?

Ewa*_*odd 12

好问题."条件复杂性"是一种代码气味.多态性是你的朋友.

条件逻辑在其初期是无辜的,当它易于理解并包含在几行代码中时.不幸的是,它很少老化.您实现了几个新功能,突然您的条件逻辑变得复杂和广泛.[Joshua Kerevsky:重构模式]

你可以做的最简单的事情之一是避免嵌套if块学会使用Guard子句.

double getPayAmount() {
if (_isDead) return deadAmount();
if (_isSeparated) return separatedAmount();
if (_isRetired) return retiredAmount();
return normalPayAmount();
};  
Run Code Online (Sandbox Code Playgroud)

我发现的另一件事情很简单,它使你的代码自我记录,是整合条件.

double disabilityAmount() {
    if (isNotEligableForDisability()) return 0;
    // compute the disability amount
Run Code Online (Sandbox Code Playgroud)

与条件表达式相关的其他有价值的重构技术包括分解条件,替换条件与访问者反向条件.


Arn*_*psa 9

规格模式可能是您正在寻找的.

摘要:

在计算机编程中,规范模式是特定的软件设计模式,通过使用布尔逻辑将业务逻辑链接在一起,可以重新组合业务逻辑.


jld*_*ont 6

我会编写一个通用的状态机,它以要比较的事物列表为基础。