Как уменьшить цикломатическую сложность?
Я работаю над классом, который отправляет RequestDTO на веб-службу. Мне нужно проверить запрос до его отправки.
Запрос может быть отправлен из трех разных мест, и для каждого типа запроса есть разные правила валидации. 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()
и возвращает boolean
Это дает мне циклическую сложность 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. Если поле требуется или не может быть нулевым, скажем так, когда создается запрос.
Создайте запрос таким образом, чтобы он был на 100% действителен и готов к работе, когда существует конструктор.
Я бы также создал эту версию String в методе Request toString(). Он должен знать, как сделать себя.