The use of enumerations to replace Boolean values is mainly based on several reasons
:: Readability
:: Expandability
:: Security prevention and control
readable
We will define
boolean
Type (true
maybefalse
) as a method parameter is more concise, but sometimes the meaning of the parameter is often not clear enough, creating a reading obstacle.
For example, a parameter may indicate "whether to enable a certain feature", but it is not possible to do so with just thetrue
cap (a poem)false
It is not obvious at a glance what their true intentions are:
setDisable(false): whether to disable or enable --!
setInvalid(false): whether it is invalid or valid --!
Believe me, this "roundabout" "double negative" expression will cost you a few brain cells for a while:)
Of course, you might say, "Instead of using a negative noun," replace it with "a direct expression."setEnable(true)
It's very intuitive to recognize that this is enabled at a glance;
Yes, that's true, but in my 10+ years of programming, believe mesetDisable(false)
I've encountered it countless times;
Another example:
You can "know at a glance" the parameters with the following codetrue
Does it mean anything?
public static void main(String[] args) {
convert("12.3456", 2, true);
}
/**
* Convert a string to a value with the specified number of decimal places
*
* @param value
* @param scale
* @param enableHalfUp Whether rounding is required.
* @return
*/
public static String convertToValue(String value, int scale, boolean enableHalfUp) {
if (enableHalfUp){
// Convert the string "rounded" to the specified number of decimal places.
}else{
//Truncate the string to the specified number of decimal places.
}
}
Of course, the IDE now have better tips, but from the "readability" point of view, is not only into the method definition to see the comments to understand, or even no comments still have to go through the code to study theboolean
What exactly are the semantics, the parameters explode further, and you can tell what each of theboolean
Does the type parameter stand for anything?
convert("12.3456", 2, true,false,true,false,true);
To expand on this, Muwan has been involved in iOS development for a while, and in the case of Objective-C, method naming uses a more intuitive format that can include multiple parameter names in a "linear narrative" to improve readability. In this case, boolean variables are often preceded by a "noun modifier", which is easier to understand, as shown below:
[NSString stringWithCString:"something" enableASCIIStringEncoding:true]
Going back to the OC language, let's see how the JDK is designed for this problem.
public static void main(String[] args) {
BigDecimal value = new BigDecimal("12.34567");
//round to two decimal places
BigDecimal roundedValue = (2, RoundingMode.HALF_UP);
(roundedValue);
}
See?BigDecimal
(used form a nominal expression)setScale
method by defining the enumeration:RoundingMode
Represents conversion rules, see:RoundingMode.HALF_UP
At a glance, you know you have to round, you don't need to look at the code at all.
This increases the readability of the while defined enumeration also supports more extensions, the second benefit is introduced immediately below:scalable;
scalability
If you need to add more states in the future, use the
boolean
Will be limited by the extension
For example, if there are currently two states:enable
(open) anddisable
(off), and in the future it will be necessary to addpragmatic
state, use theboolean
It is not flexible enough. Enumerations, on the other hand, are easily extensible and can clearly represent more states.
utilizationboolean
Expresses the functional state:
public void configureFeature(boolean enable) {
if (enable) {
// Enabling Functions
} else {
// disabling function
}
}
Use enumerations to express functional states:
public enum FeatureMode {
ENABLED,
DISABLED,
MAINTENANCE
}
public void configureFeature(FeatureMode mode) {
switch (mode) {
case ENABLED:
// Enabling Functions
break;
case DISABLED:
// disabling function
break;
case MAINTENANCE:
// Maintenance Status
break;
default:
throw new IllegalArgumentException("Unknown mode: " + mode);
}
}
type safety
Incorrect use of the Boolean wrapper class may raise a null pointer exception;
Let's throw a question out there first: the packaging classBoolean
How many "values" are there?Boolean
is an enumeration containing two values: cap (a poem)
;But don't forget, it can also be
null
;
A real-life on-line failure thatBoolean
have been used incorrectly in some cases.May cause a null pointer exception;
Example Suppose you are modifying a method on an old system that returnsBoolean
, there are thousands of lines of code:
public static void main(String[] args) {
if (checkIfMatched("Dummy")){
("matched");
}
}
/**
* An unusually complex method on an old system with thousands of lines
* @param str
* @return
*/
public static Boolean checkIfMatched(String str) {
Boolean matched.
// Assuming there is complex processing logic here, use dummy instead for now
if ("Dummy".equals(str)) {
matched = true; } else { if ("Dummy".equals(str))
} else {
Boolean matched = false; }
}
return matched; }
}
It's fine for now, but the complexity rises steeply as the functionality iterates, and in one particular branch, there's no explanation of theBoolean
Assignments, at least at compile time, do not report errors:
public static void main(String[] args) {
if (checkIfMatched("Dummy")) {
("matched");
}
}
/**
* An unusually complex method on an old system with thousands of lines
*
* @param str
* @return
*/
public static Boolean checkIfMatched(String str) {
Boolean matched = null; // Assume there is: complex processing logic here, temporarily use dummy instead.
// Assuming there is complex processing logic here, use dummy instead for now
if ("Dummy".equals(str)) {
// Simulation: as the code evolves, it is possible that matched is not assigned a value
if (false) {
matched = true; }
}
} else {
matched = false; }
}
return matched; }
}
This time of year, danger creeps in, remember the question above:
PackagingBoolean
How many "values" are there?
present .checkIfMatched()
Methods return three different values in different situations:true/false/null
here arenull
is very dangerous, if upstream use the following way to determine the conditions, consider whether there is a problem?
if (checkIfMatched("Dummy")) {
("matched");
}
First of all there is no compilation error here, but hereif
The box is automatically unpacked at the condition, fornull
The value will getNullPointerException
Exception;
A little summary
Going back to: "Which scenarios suggest using enums to replace booleans", I think it depends on how easy the function point is to change to make a comprehensive assessment: "The easier it is to change, the less you can let the complexity diverge, the more you have to converge from one place, just imagine the nextBoolean
The change in methodology is not to assess all upstream operations."
So it's not a complete overthrow of the Boolean value, Muwan brother here is also just to throw out some code optimization means for reference only.