Уменьшить сложность 14 для метода
Pmd сказал мне, что этот метод (thirdRowsValidation) имеет сложность 14, но я не могу найти шаблон, чтобы уменьшить код.
indexBookngEnd, indexTravelStart... все эти переменные являются индексами из другого массива, созданного в другой итерации цикла (заголовок столбцов файла CSV) - Ref1
public void thirdRowsValidation(String thirdRowCsv) {
String[] lines1 = thirdRowCsv.split(",");
for (int i = 0; i < lines1.length; i++) {
if (indexBookngEnd == i && "".equals(temporalValidateBookngEnd)) {
temporalValidateBookngEnd = (" to " + lines1[i] + "\n");
}
if (indexBookngStart == i
&& !("".equals(temporalValidateBookngEnd))) {
finalOutput.append("Then it should have booking window ");
indexBookngStart = -1;
}
if (indexTravelEnd == i && "".equals(temporalValidateTravelEnd)) {
temporalValidateTravelEnd = (" to " + lines1[i] + "\n");
}
if (indexTravelStart == i
&& !("".equals(temporalValidateTravelEnd))) {
finalOutput.append("Then it should have travel window ");
String idHeaderColumn = String.format("%1$-" + 5 + "s", "id");
String typeHEaderColumn = String.format("%1$-" + 50 + "s","type");
finalOutput.append("| ");
finalOutput.append(idHeaderColumn);
indexTravelStart = -1;
}
if (indexPackageDescription == i) {
temporalPackages = String.format("%1$-" + 50 + "s", lines1[i]);
}
if (indexPackageCode == i
&& !(lines1[i].matches("[+-]?\\d*(\\.\\d+)?"))
&& indexTravelStart == -1) {
finalOutput.append("| ");
}
}
}
Ref1:
public void secondRowValidation(String secondRowCsv) {
String[] lines1 = secondRowCsv.split(",");
for (int i = 0; i < lines1.length; i++) {
if ("Bookng start".equalsIgnoreCase(lines1[i])) {
indexBookngStart = i;
}
if ("Bookng end".equalsIgnoreCase(lines1[i])) {
indexBookngEnd = i;
}
Массив из \n и позже для ","
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);
}
}
Итак, что у меня есть: - Метод thirdRowsValidation() имеет NPath-сложность 649 - Метод thirdRowsValidation имеет цикломатическую сложность 14.
В конце я получаю текст, подобный этому, только для вас, ребята, есть идея:
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 |
2 ответа
Сложность метода так высока, потому что он делает много разных вещей. Попробуйте сделать одну вещь на метод.
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
}
}
Попробуйте передать все, что нужно методу в качестве одного из аргументов. Метод не должен полагаться на значение поля, установленного в другом методе. Это снижает сложность, а также облегчает чтение, понимание и тестирование кода.
Если метод или класс имеют высокую сложность, это обычно означает, что он пытается сделать слишком много разных вещей одновременно. Сделайте шаг назад и постарайтесь выявить различные вещи, которые он делает, и реализовать их отдельно. Это автоматически приведет к коду с низкой сложностью.
Извлечение внутреннего цикла в новый метод обычно является быстрым взломом, который поможет уменьшить сложность одного метода, но не сложность класса в целом.
Вы могли бы начать с перемещения внутренней логики for
-перейти в отдельный метод:
public void thirdRowsValidation(String thirdRowCsv) {
String[] lines1 = thirdRowCsv.split(",");
for (int i = 0; i < lines1.length; i++) {
doSomethingWithTheRow(i, lines[i]);
}
}
И внутри doSomethingWithTheRow()
метод, ваш внутренний код будет находиться:
doSomethingWithTheRow(int i, String row) {
if (indexBookngEnd == i && "".equals(temporalValidateBookngEnd)) {
temporalValidateBookngEnd = (" to " + row + "\n");
}
if (indexBookngStart == i
&& !("".equals(temporalValidateBookngEnd))) {
...
Не уверен, что это снижает сложность до уровня, который вы считаете приемлемым, но это первое начало. Кроме того, это принцип чистого кода, определенный дядей Бобом. У вас есть небольшие методы, которые выполняют одну функцию (теперь метод извлекает только отдельные строки, а затем вызывает другие методы, чтобы сделать что-то с этой строкой), и которые, ну, в общем, короткие. А именно, SRP
(Принцип единой ответственности) и KISS
(Держи это просто, глупо) принципы.