Java 将方法的复杂性降低14

Java 将方法的复杂性降低14,java,pmd,cyclomatic-complexity,Java,Pmd,Cyclomatic Complexity,Pmd告诉我这个方法(thirdRowsValidation)的复杂度为14,但我无法找到减少代码的模式 indexBookngEnd,indexTravelStart。。。所有这些变量都是在另一个循环迭代中生成的其他数组的索引(csv文件列的标题)-参考1 您可以首先将for-循环的内部逻辑移动到一个单独的方法中: public void thirdRowsValidation(String thirdRowCsv) { String[] lines1 = thirdRowCsv.sp

Pmd告诉我这个方法(thirdRowsValidation)的复杂度为14,但我无法找到减少代码的模式

indexBookngEnd,indexTravelStart。。。所有这些变量都是在另一个循环迭代中生成的其他数组的索引(csv文件列的标题)-参考1


您可以首先将
for
-循环的
内部逻辑移动到一个单独的方法中:

public void thirdRowsValidation(String thirdRowCsv) {
    String[] lines1 = thirdRowCsv.split(",");
    for (int i = 0; i < lines1.length; i++) {
      doSomethingWithTheRow(i, lines[i]);
    }
}

不确定这是否会将复杂性降低到您认为可以接受的程度,但这是第一个开始。此外,它是由Bob叔叔定义的干净代码原则。您有一些小方法,只做一件事(该方法现在只提取单行,然后调用其他方法来处理该行),它们很短。即
SRP
(单一责任原则)和
KISS
(保持简单、愚蠢)原则。

该方法的复杂性很高,因为它做了很多不同的事情。尝试每种方法做一件事

public String getStoryFromCsv(String csv) {
    StringBuilder story = new StringBuilder();
    String[] lines = csv.split("\n”);
    appendBookingWindowValidation(story, lines[0]);
    appendTravelWindowValidation(story, lines[1]);
    appendOnlinePackageValidation(story, lines);
    return story.toString();
}

private void appendBookingWindowValidation(StringBuilder story, String firstLine) {
    story.append("Then it should have booking window ");
    // extract start and end date from 'firstLine'
    // and append them to the story
}

private void appendTravelWindowValidation(StringBuilder story, String secondLine) {
    story.append("Then it should have travel window ");
    // extract start and end date from 'secondLine'
    // and append them to the story
}

private void appendOnlinePackageValidation(StringBuilder story, String[] lines) {
    story.append("And it should have online packages:\n")
         .append("| id    | type                                              |\n");
    for (int i = 2 ; i < lines.length; i++) {
      // create and append a row of the online packages table
   }
}
公共字符串getStoryFromCsv(字符串csv){
StringBuilder故事=新建StringBuilder();
字符串[]行=csv.split(“\n”);
appendBookingWindowValidation(故事,行[0]);
附录1(故事,行[1]);
appendOnlinePackageValidation(故事、行);
返回story.toString();
}
私有void appendBookingWindowValidation(StringBuilder故事,字符串第一行){
附加(“那么它应该有预订窗口”);
//从“第一行”提取开始和结束日期
//并将它们附加到故事中
}
私有窗口验证(StringBuilder故事,字符串第二行){
附加(“那么它应该有旅行窗口”);
//从“第二行”提取开始和结束日期
//并将它们附加到故事中
}
私有void appendOnlinePackageValidation(StringBuilder故事,字符串[]行){
story.append(“它应该有在线包:\n”)
.append(“|id | type |\n”);
对于(int i=2;i
尝试将方法所需的所有内容作为参数传递。方法不应依赖于在其他方法中设置的字段值。这可以降低复杂性,并使代码更易于阅读、理解和测试

如果一个方法或类具有很高的复杂性,那么它通常意味着它试图同时做太多不同的事情。后退一步,尝试识别它所做的不同事情并分别实现它们。这将自动生成低复杂性的代码


将内部循环提取到一个新方法中通常是一个快速的技巧,这将有助于降低单个方法的复杂性,但不会降低整个类的复杂性。

您应该首先将循环的内容提取到单独的方法中。这将降低复杂性。然后,考虑到您似乎有相当多的字段或全局变量bles,通过将该状态移动到一个单独的对象中,这可能会有点重构,因为您可以移动该状态对象,所以进一步重构会更容易一些。但这些只是猜测,所以从IntelliJ的建议开始:-)我理解…这就是我在这里做的示例…如果(j==0){firstRowValidation(arrayPerRow);}但是正如你所看到的,有两个主循环是需要的,我无法更改,但是你可以将所有内容从第4行移到最后一行,但第三行移到一个方法中,这样你的
thirdRowsValidation
将只包含
for
-循环,然后为每个
I
调用一个方法。我不太明白..你能不能e用代码解释国际单项体育联合会将如何运作?
public String getStoryFromCsv(String convert) {
        String[] lines = convert.split("(\n)");
        for (int j = 0; j < lines.length; j++) {

            arrayPerRow = lines[j];
            if (j == 0) { // get marketing type and number
                firstRowValidation(arrayPerRow);
            }
            if (j == 1) { // get headers
                secondRowValidation(arrayPerRow);
            }
            if (j > 1) { // get info and append according to headers
                thirdRowsValidation(arrayPerRow);
            }

        }
Then it should have booking window 8/8/16 to 10/8/16
Then it should have travel window 11/6/16 to 12/25/16
And it should have online packages:
| id    | type                                              |
| 34534 | aaa Pkg                                           |
| D434E | MKW Pkg + asdasdasdasdasdasdas                    |
| F382K | sds Pkg + Ddding                                  |
| X582F | OYL Pkg + Deluxe Dining                           |
public void thirdRowsValidation(String thirdRowCsv) {
    String[] lines1 = thirdRowCsv.split(",");
    for (int i = 0; i < lines1.length; i++) {
      doSomethingWithTheRow(i, lines[i]);
    }
}
doSomethingWithTheRow(int i, String row) {
    if (indexBookngEnd == i && "".equals(temporalValidateBookngEnd)) {
        temporalValidateBookngEnd = (" to " + row + "\n");

    }
    if (indexBookngStart == i
                && !("".equals(temporalValidateBookngEnd))) {
    ...
public String getStoryFromCsv(String csv) {
    StringBuilder story = new StringBuilder();
    String[] lines = csv.split("\n”);
    appendBookingWindowValidation(story, lines[0]);
    appendTravelWindowValidation(story, lines[1]);
    appendOnlinePackageValidation(story, lines);
    return story.toString();
}

private void appendBookingWindowValidation(StringBuilder story, String firstLine) {
    story.append("Then it should have booking window ");
    // extract start and end date from 'firstLine'
    // and append them to the story
}

private void appendTravelWindowValidation(StringBuilder story, String secondLine) {
    story.append("Then it should have travel window ");
    // extract start and end date from 'secondLine'
    // and append them to the story
}

private void appendOnlinePackageValidation(StringBuilder story, String[] lines) {
    story.append("And it should have online packages:\n")
         .append("| id    | type                                              |\n");
    for (int i = 2 ; i < lines.length; i++) {
      // create and append a row of the online packages table
   }
}