Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to simplify conditional expressions

2025-03-30 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article mainly introduces "how to simplify conditional expressions". In daily operation, I believe that many people have doubts about how to simplify conditional expressions. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "how to simplify conditional expressions"! Next, please follow the editor to study!

Preface

Compared with process-oriented programming, there are relatively fewer conditional expressions in object-oriented programming, because a lot of conditional behaviors can be dealt with by polymorphic mechanisms; but sometimes we encounter that there is no difference between conditional expressions written by some partners and process-oriented programming, for example, I have encountered this piece of code:

The whole code has three layers, and each layer has if-else. The logic of this code is difficult to understand. What is even more disgusting is that the caller of this method and other methods called are also several layers of if-else nesting. In addition, a big problem with this code is that the passed parameter object is modified many times in the interior and other methods called, so it is more difficult to understand. It's too difficult to understand by relying on ordinary people's single-core CPU. To maintain this code, I feel like my body is hollowed out.

Sometimes we may encounter more complex conditional logic, we need to find a way to divide it into small pieces to separate the branch logic from the operation details; look at a programmer's code code, first see whether his conditional expression is concise and easy to understand; today we will share the common methods of simplifying conditional expressions to practice their own code morality.

Decomposition conditional expression

Complex conditional logic is one of the most common places that lead to an increase in complexity. in addition, if there is a lot of logic inside the branch, we will eventually get a large function, and the readability of a long method itself will decline. so we need to divide the large methods into multiple methods, and choose a method name for each method that is easy to clearly express the internal logic, so the readability will be greatly improved.

For example:

If (date.before (SUMMER_START) | | date.after (SUMMER_END)) {charge = quantity * _ winterRate + _ winterServiceCharge;} else {charge = quantity * _ summerRate}

Many people may not feel the need to extract the method of this kind of code, but if we want to understand this code, we still have to think about it before we know what we are doing; let's modify it next.

If (notSummer (date)) {charge = winterCharge (quantity);} else {charge = summerCharge (quantity);} private boolean notSummer (Date date) {date.before (SUMMER_START) | | date.after (SUMMER_END)} private double summerCharge (int quantity) {return quantity * _ summerRate;} private double winterCharge (int quantity) {return quantity * _ winterRate + _ winterServiceCharge;}

After this modification, is it very clear that good code itself does not need to write comments (the code is self-explanatory), let alone write any comments inside the method? sometimes we see that some students will write comments inside the method every few lines, which shows that the self-explanatory nature of the code is not good enough, and the readability of the code can be improved through the example just now.

Merge conditional expression

When we encounter multiple if condition judgments in a piece of code, but the logic inside the condition is similar, we can merge the conditions together and extract the method.

Example 1:

Double disabilityAmount () {if (_ seniortiy 12) return 0; if (_ isPartTime) return 0; / / omit.}

The results returned by the conditions here are all the same, so let's merge the conditions first.

Double disabilityAmount () {if (_ seniortiy 12 | | _ isPartTime) {return 0;} / omitted.}

Next, let's extract the judgment condition into a method to improve readability.

Double disabilityAmount () {if (isNotEligibleForDisableility ()) {return 0;} / omitted.} boolean isNotEligibleForDisableility () {return _ seniortiy 12 | | _ isPartTime;}

Example 2:

If (onVacation ()) {if (lengthOfService () > 10) {return 2;}} return 1

Merged code

If (onVacation () & & lengthOfService () > 10) {return 2} return 1

Then we can use the ternary operator to simplify the modified code:

Return onVacation () & & lengthOfService () > 10? 2: 1

Through these two examples, we can see that conditional logic and branch logic are separated into different methods, and then we will find that it is so simple and handy to improve the readability of the code; so a good method of extraction is the key; I think there should be applause here.

Merge duplicate conditional clips

Let's first look at an example of a 50% discount for children under the age of 10.

If (ageLt10 (age)) {price = price * 0.5; doSomething ();} else {price = price * 1; doSomething ();}

We find that different branches execute the same terminal code logic. At this time, we can extract this code outside the condition judgment. The example here is relatively simple. What we usually encounter in our work may not be such a simple method, but many lines of complex logic conditions. We can first extract this code into a method, and then put the call to this method before or after the condition judgment.

Modified code

If (ageLt10 (age)) {price = price * 0.5;} else {price = price * 1;} doSomething ()

When we encounter the same logic code in try-catch, we can also use this way to handle the

Wei statement replaces nested conditional expression

Once there is a deep nesting logic in the method, it is difficult to understand the main line of execution. When if-else is used to indicate that both branches are equally important and are the mainline process, as shown in the following figure

But most of the time we will encounter only one mainline process, and the rest are individual exceptions, in which case it is not appropriate to use if-else, and we should replace nested expressions with guard statements.

Example 1:

In the compensation system, special rules are used to deal with the salaries of dead employees, expatriate employees and retired employees, which are rare and do not belong to normal logic

Double getPayAmount () {double result; if (isDead) {result = deadAmount ();} else {if (isSeparated) {result = separatedAmount ();} else {if (isRetired) {result = retiredAmount ();} else {result = normalPayAmount ();}} return result;}

In this code, we can't see what the normal process is. These occasional situations cover up the normal process. Once an accident occurs, we should return directly. Guiding the maintainer of the code to see a useless else will only hinder understanding; let's modify it with return.

Double getPayAmount () {if (isDead) {return deadAmount ();} if (isSeparated) {return separatedAmount ():} if (isRetired) {return retiredAmount ();} return normalPayAmount ();} Polymorphic substitution condition expression

Sometimes we come across a structure like if-else-if or switch-case, which is not only untidy, but also difficult to understand when faced with complex logic. This situation can be modified by object-oriented polymorphism.

For example, if you are developing a game, you need to write a method to obtain the attack power of Bartizan, Archer and Tank. After two hours of hard work, you have finally completed this function. The code after development is as follows:

Int attackPower (Attacker attacker) {switch (attacker.getType ()) {case "Bartizan": return 100; case "Archer": return 50; case "Tank": return 800;} throw new RuntimeException ("can not support the method");}

There is no problem after self-test, and you are in a good mood at this time.

When you submit the code to the leader review, the leader (thinking about this for two hours, it's too obvious to touch the fish at work) directly reply to the code implementation is not elegant enough, rewrite

1. Enumerated polymorphism

Although you are very upset when you see this reply, you can't help it. After all, you still have to make a living here; you still answer OK in your mouth.

You thought about it for a while and thought of using enumerated polymorphisms to implement it, just do it, so you wrote the next version.

Int attackPower (Attacker attacker) {return AttackerType.valueOf (attacker.getType ()). GetAttackPower ();} enum AttackerType {Bartizan ("Archer") {@ Override public int getAttackPower () {return 100;}}, Archer ("Archer") {@ Override public int getAttackPower () {return 50 }, Tank ("tank") {@ Override public int getAttackPower () {return 800;}}; private String label; Attacker (String label) {this.label = label;} public String getLabel () {return label;} public int getAttackPower () {throw new RuntimeException ("Can not support the method");}}

Submit the leader review again this time, and it has passed smoothly. You think that get has reached the point of leadership.

two。 Quasi-polymorphism

Did not expect that you are not happy for a few days, and received a new demand, this method of obtaining attack power needs to be modified, and the attack power varies according to the level of the attacker; you consider that the attack power of the last version is fixed, it is more appropriate to use enumeration, but this modification should be based on the attacker's own level to calculate the attack, if you use enumeration may not be appropriate At the same time, you also think that the simple implementation was led last time, and if it is implemented on the last enumerated version, it may not get a good result; finally, you decide to use the polymorphism of the class to do it.

Int attackPower (Attacker attacker) {return attacker.getAttackPower ();} interface Attacker {default int getAttackPower () {throw new RuntimeException ("Can not support the method");}} class Bartizan implements Attacker {public int getAttackPower () {return 100 * getLevel ();}} class Archer implements Attacker {public int getAttackPower () {return 50 * getLevel () }} class Tank implements Attacker {public int getAttackPower () {return 800 * getLevel ();}}

After the completion, it was submitted to the leader review, and the leader smiled and passed the code review.

3. Strategy mode

You thought it would be over, but as a result, the plan could not catch up with the change. After the game was launched, the effect was not very good. You received another change in demand. The calculation of attack power can not be so rough. We need backstage configuration rules to increase the attack power of some participating players according to the rules.

You are very angry and think to yourself: haven't you heard that you don't need a gun to kill a programmer? just change the requirement three times. MD, do you want me to die?

Get angry, but don't dare to show it. Who told you to be the leader? let's do it.

Considering that rules are added to the logic this time, the rules themselves can be designed simply or very complicated. if the later rules become more complex, then the whole target class will be particularly bloated and not scalable. So instead of using class polymorphism to implement this time, consider using policy mode. The code is as follows:

/ / define the interface of computing class interface AttackPowerCalculator {boolean support (Attacker attacker); int calculate (Attacker attacker);} / Arrow Tower attack force calculation class class BartizanAttackPowerCalculator implements AttackPowerCalculator {@ Override public boolean support (Attacker attacker) {return "Bartizan" .equals (attacker.getType ());} @ Override public int calculate (Attacker attacker) {/ / calculate attack force return doCalculate (getRule ()) according to rules }} / / Archer attack force calculation class class ArcherAttackPowerCalculator implements AttackPowerCalculator {@ Override public boolean support (Attacker attacker) {return "Archer" .equals (attacker.getType ());} @ Override public int calculate (Attacker attacker) {/ / calculate attack power according to the rules return doCalculate (getRule ()) }} / / Tank attack force calculation class class TankAttackPowerCalculator implements AttackPowerCalculator {@ Override public boolean support (Attacker attacker) {return "Tank" .equals (attacker.getType ());} @ Override public int calculate (Attacker attacker) {/ / calculate attack force return doCalculate (getRule ()) according to rules;}} / aggregate all computing classes class AttackPowerCalculatorComposite implements AttackPowerCalculator {List calculators = new ArrayList () Public AttackPowerCalculatorComposite () {this.calculators.add (new TankAttackPowerCalculator ()); this.calculators.add (new ArcherAttackPowerCalculator ()); this.calculators.add (new BartizanAttackPowerCalculator ());} @ Override public boolean support (Attacker attacker) {return true } @ Override public int calculate (Attacker attacker) {for (AttackPowerCalculator calculator: calculators) {if (calculator.support (attacker)) {calculator.calculate (attacker);}} throw new RuntimeException ("Can not support the method");}} / / the int attackPower (Attacker attacker) {AttackPowerCalculator calculator = new AttackPowerCalculatorComposite () is calculated by calling the aggregate class at the entrance Return calculator.calculate (attacker);}

You submitted the code to the leader review again, and the leader was very satisfied with it and praised you and said: young man, good, rapid progress, give you a like; you replied: thank the leader for his approval (of course, after all, I have figured out where your point is)

If you feel satisfied with the completion of this function this time, please give me a like and follow the comments.

Introduce assertions

The last operation to simplify conditional expressions is to introduce assertions, which is relatively simple, and the Spring framework itself provides utility classes for assertions, such as the following code:

Public void getProjectLimit (String project) {if (project = = null) {throw new RuntimeException ("project can not null");} doSomething ();}

The code after adding the assertion of Spring

Public void getProjectLimit (String project) {Assert.notNull (project, "project can not null"); doSomething ();} at this point, the study of "how to simplify conditional expressions" is over, hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report