如何降低环状复杂性?

2022-09-01 07:37:32

我正在研究一个将 RequestDTO 发送到 Web 服务的类。我需要在发送请求之前验证请求。

请求可以从3个不同的地方发送,并且每个“请求类型”都有不同的验证规则,例如,request1必须具有名称和电话号码,request2必须具有地址等)

我有一个DTO,其中包含一长串字段(姓名,地址,城市,电话号码等),无论它是哪种类型的请求,它都是相同的DTO发送。

我已经创建了3种不同的验证方法,并根据类型调用了适当的方法。

在上述每种方法中,我都有一长串 if-else 来检查每种请求类型所需的字段。

private void validateRequest1(Request request) {
    StringBuilder sb = new StringBuilder();
    if (null == request) {
        throw new IllegalArgumentException("Request is null");
    }
    if (isFieldEmpty(request.getName())) {  *see below
        sb.append("name,"));
    }
    if (isFieldEmpty(request.getStreet())) {
        sb.append("street,"));
    }
    ...

isFieldEmpty()检查字符串是否为 null,并返回一个布尔值isEmpty()

这给了我其中一种方法的28的循环复杂性,所以我的问题是。是否有可能降低这种复杂性?- 如果是这样,我该怎么做?

最终,我需要检查很多字段,如果没有大量检查,我就无法看到如何做到这一点:/


答案 1

一个简单的方法是将检查提升为单独的方法:

private String getAppendString(String value, String appendString) {
    if (value == null || value.isEmpty()) {
        return "";
    }
    return appendString;
}

然后,您可以使用此方法代替块:if

sb.append(getAppendString(request.getStreet(), "street,");

这将把复杂性从28降低到3。永远记住:高复杂性计数表明一种方法试图做太多的事情。复杂性可以通过将问题分成更小的部分来处理,就像我们在这里所做的那样。


答案 2

另一种方法是在 Request 对象本身中强制执行该协定。如果字段是必填字段或不能为 null,请在创建请求时说明。

以 100% 有效且在构造函数存在时准备就绪的方式创建请求。

我还会在 Request toString() 方法中创建该 String 版本。它应该知道如何渲染自己。


推荐