问题
I'm working on a class which sends a RequestDTO to a Web Service. I need to validate the request before it is sent.
The request can be sent from 3 different places and there are different validation rules for each "requesttype", e.g. request1 must have name and phonenumber, request2 must have address, etc)
I have a DTO which contains a long list of fields (name, address, city, phonenumber, etc.) and it is the same DTO sent no matter which type of request it is.
I have created 3 different validation methods and based on the type the appropriate method is called.
In each of these methods I have a long list of if-else's to check for the fields that are necessary for each request type.
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()
checks the string for null and isEmpty()
and returns a boolean
This gives me a cyclomatic complexity of 28 in one of those methods so my question is.. is it possible to reduce this complexity? - if so, how would I go about doing so?
Ultimately I need to check a lot of fields and I cannot see how this can be done without lots of checks :/
回答1:
An easy way is to promote the check into a separate method:
private String getAppendString(String value, String appendString) {
if (value == null || value.isEmpty()) {
return "";
}
return appendString;
}
And then you can use this method instead of the if
blocks:
sb.append(getAppendString(request.getStreet(), "street,");
This will reduce complexity from 28 down to 3. Always remember: high complexity counts are an indication that a method is trying to do too much. Complexity can be dealt with by dividing the problem into smaller pieces, like we did here.
回答2:
Another approach would be to enforce that contract in the Request object itself. If a field is required or can't be null, say so when the Request is created.
Create the Request in such a way that it's 100% valid and ready to go when the constructor exists.
I'd also create that String version in the Request toString() method. It should know how to render itself.
来源:https://stackoverflow.com/questions/16418038/how-to-reduce-cyclomatic-complexity