2013-05-07 17 views
11

Pracuję nad klasą, która wysyła RequestDTO do usługi sieci Web. Muszę zweryfikować żądanie przed jego wysłaniem.Jak zmniejszyć złożoność cykliczności?

Żądanie może zostać wysłane z 3 różnych miejsc i istnieją różne reguły sprawdzania poprawności dla każdego "requesttype", np. request1 musi mieć nazwę i numer telefonu, request2 musi mieć adres, itp.)

Mam DTO, które zawiera długą listę pól (nazwa, adres, miasto, numer telefonu itp.) i jest to ten sam DTO wysłany bez względu na jakiego typu jest to żądanie.

Stworzyłem 3 różne metody sprawdzania poprawności i na podstawie typu wywoływanej odpowiedniej metody.

W każdej z tych metod mam długą listę if-else, aby sprawdzić pola, które są niezbędne dla każdego typu żądania.

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() sprawdza ciąg dla nieważną i isEmpty() i zwraca wartość logiczną

To daje mi cyclomatic złożoność 28 w jednej z tych metod, więc moje pytanie brzmi .. czy to możliwe, aby zmniejszyć tę złożoność? - jeśli tak, to w jaki sposób chciałbym to zrobić?

Ostatecznie muszę sprawdzić wiele dziedzin i nie widzę w jaki sposób można to zrobić bez partii kontrole:/

+1

Mój pomysł byłby następujący: Użyj jakiegoś obiektu 'FieldChecker', który obejmuje pustkę (lub inną) i akcję, która ma zostać wykonana (' sb.append() ') itd. I zapętlaj listę takie obiekty. Dzięki temu kod staje się bardziej przejrzysty, ponieważ trzeba jednoznacznie zdefiniować wyniki i dane wejściowe tego sprawdzenia. – millimoose

Odpowiedz

22

Łatwym sposobem jest promowanie czek na oddzielnej metody:

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

a następnie można użyć tej metody zamiast if bloków:

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

Spowoduje to zmniejszenie złożoności od 28 do 3. Zawsze pamiętaj: coun wysokiej złożoności ts wskazują, że metoda próbuje zrobić zbyt wiele. Złożoność można rozwiązać, dzieląc problem na mniejsze części, tak jak tutaj.

1

Innym podejściem byłoby egzekwowanie tej umowy w samym obiekcie Request. Jeśli pole jest wymagane lub nie może mieć wartości null, powiedz to podczas tworzenia żądania.

Utwórz żądanie w taki sposób, aby było w 100% poprawne i gotowe do pracy, gdy istnieje konstruktor.

Chciałbym również utworzyć tę wersję String w metodzie Request toString(). Powinien wiedzieć, jak się wyrenderować.