preface
Some time ago when I was reading the code written by others, I found that there were a lot of if-else statements nested in several layers in the body of some business-related methods. First of all, I don’t personally discourage writing if-else statements, and I have to say, a lot of times, if you’re writing logic and you’re using if-else, it looks pretty straightforward, but if you’re abusing if-else, you’re nesting multiple layers, Each case also contains a lot of logic, so using if-else is not worth the cost in terms of readability. And in some cases, you may not need as much if-else, or you can use other encoding methods to achieve reduced if-else effects.
There are many ways to reduce the use of if-else, such as the design pattern-level policy pattern or the chain of responsibility pattern. And here to share with you some personal daily coding process often used, relatively simple, from the level of coding habits, to reduce some unnecessary if-else use. Because I am only a rookie, if there is a wrong place to write, please criticize correct.
Some encoding that reduces if-else
Method 1: Return in advance
Let’s start with a code example:
if (condition1) {
if (condition2) {
return getSomething();
} else {
return 0; }}else {
return 0;
}
Copy the code
The modified code is as follows:
// It is best to describe the logic judged by this flag with additional comments
booleanflag = ! condition1 || (condition1 && ! condition2)if(flag) {
return 0;
}
if (condition1 && condition2) {
return getSomething();
}
Copy the code
If there is logic that is known to return a fixed value under certain conditions, you can extract this logic into a separate if-else block and put it in front of other if-else blocks. When this condition is met, you can return the fixed value in advance. The most immediate effect of this approach is to reduce the amount of nesting of if-else.
Method 2: Use the ternary operator
Here is an example of a business scenario:
Query the list of image urls for a comment (if any, the list of image urls for the comment is stored in the comment table as a JSON array string)
The code before modification is as follows:
Comment comment = getById(commentId);
if (Objects.isNull(comment)) {
throw new RuntimeException("Comment does not exist or has been deleted");
}
String imgListStr = comment.getImgList();
if(StringUtils.isEmpty(imgListStr)) {
return null;
}
return JSON.parseArray(imgListStr, String.class);
Copy the code
Revised:
Comment comment = getById(commentId);
if (Objects.isNull(comment)) {
throw new RuntimeException("Comment does not exist or has been deleted");
}
String imgListStr = comment.getImgList();
return StringUtils.isEmpty(imgListStr)) ?
null : JSON.parseArray(imgListStr, String.class);
Copy the code
Method 3: Use Assert assertions
In the process of writing business code, if you need to judge some specific conditions, and when the conditions are not met, you need to throw an exception. For this scenario, in addition to using the if approach in the trinary operator example above, you can also use the Assert tool class provided by the Spring Framework.
Common apis include:
- isTrue(boolean expression , String message) : 当
expressio == false
“, will throw an exception, exceptionmessage
Is the second input parameter; - void notNull(@Nullable Object object, String message) :Same as above, when
object == null
Is thrown an exception. - void notEmpty(@Nullable Collection<? > collection, String message) :As above, when the set object is
null
Or if the collection element is empty, an exception is thrown. - .
There are many other methods, you can directly look at the source parsing, of course, in fact isTrue() is sufficient, if you need to be more semantic, you can use the corresponding API.
Code before modification:
if (Objects.isNull(comment)) {
throw new RuntimeException("Comment does not exist or has been deleted");
}
Copy the code
Modified code:
Assert.isTrue(Objects.nonNull(comment),"Comment does not exist or has been deleted");
Assert.notNull(comment,"Comment does not exist or has been deleted");
Copy the code
Now Assert tool method can only throw a single a Java exception. Lang. IllegalArgumentException, if you need to customize the exception thrown by the, then this method is not applicable.
Option 4: Use Optional
Optional is a new java8 feature. It is used to verify the null value of an object and perform subsequent operations, such as throwing exceptions and null replacement.
Among them, I often use several methods:
- Static
Optional
ofNullable(T value) : wrap the object with Optional;
- T orElse(T other) :The object in Optional is
null
Returns the object of the input parameter. - T orElseGet(Supplier<? extends T> other) :The object in Optional is
null
When to return toSupplier
The value provided; - T orElseThrow(Supplier<? extends X> exceptionSupplier) :The object in Optional is
null
When thrownsupplier
Custom exception provided
Code examples:
Message message1 = Optional.ofNullable(getById(messageId))
.orElseThrow(() -> new RuntimeException("The message does not exist!));
Message message2 = Optional.ofNullable(getById(messageId))
.orElse(new Message());
Message message3 = Optional.ofNullable(getById(messageId))
.orElseGet(Message::new);
Copy the code
Since I need to perform null value judgment more scenarios in daily life, when the data query is completed from the database, I need to perform null value judgment on the query results. Since the persistence layer framework used by my company is Mybatis, unlike the default JPA of Spirng Boot 2.x, the DAO layer method supports the return value of Optional, so if Optional is needed here, The query results can only be wrapped manually using the first method listed above.
Of course, IDEA has already provided us with hotkeys for this packaging mode, as shown in the figure below:
conclusion
Here are some ways to reduce if-else coding habits. Among these ways, I personally think the most obvious effect is the first way to return early, many times, return early can also be very good to reduce the complexity of a piece of code.
Of course, if you have to use a lot of if-else to control the logic, it’s a good idea to comment each condition.