My main language is Java, so a personal summary of what I'm particularly concerned about in Java The interface and design are not mentioned in this article because the details are important.
The wider the scope, the more the variable plays. It also makes it easier to embed bugs such as use and changes at unexpected timings. I want to keep the scope to the minimum necessary.
Suppose you have a find method that queries a name from an array of IDs (int).
String name;
for (int id : identities) {
name = find(id);
//Something to do with name
}
In this code example, the name variable is defined outside the loop, but if name is used only inside the loop, defining it inside the loop narrows the scope.
for (int id : identities) {
final String name = find(id);
//Something to do with name
}
Although it affects the scope mentioned above, the naming of variable names and method names needs to be stricter according to the scope. Conversely, a narrow scope eliminates the need for strictness.
Loop counters such as ʻint iare extremely short cases, but variables used within 2-3 lines can be simple variable names such as
name and ʻage
.
On the other hand, constants need to be strict according to the domain.
For example, public static final String DEFAULT_USER_NAME_VALUE =" Anonymous ";
.
If there is a type in ʻUSER`, the constant will increase by that amount, and the variable name will need to be stricter, which will make it longer.
If you want to use a variable that means some name inside or outside the loop, you'll need to do something like ʻuserName ʻadminUserName
instead of a name like name
and name2
.
Variables can be immutable except for some counters.
In the case of mutable variables, changes and namespace overwriting may occur at unexpected timings.
Some IDEs, such as IntelliJ, even local variables are defined in final when the variable is created.
However, be aware that the contents of Map and List can be rewritten even if the variables themselves are final.
In the case of Java, it is desirable to return a deepcopy or ʻUnmodifiableList before returning a method that returns
private final List`, which is an instance variable.
private final List<String> nameList = new ArrayList<>();
public List<String> getNameList() {
return nameList;
}
I would like to consider replacing this with the following.
private final List<String> nameList = new ArrayList<>();
public List<String> getNameList() {
return Collections.unmodifiableList(nameList);
}
I think there are many cases where String and int constants are used (although they are not primitives), but I would like to consider replacing them with enumeration types and classes that represent them. For example, suppose that there is a process to write data to a file, and the following constants are prepared as the write mode.
/**
*Addendum mode
*/
public static final String WRITE_MODE_APPEND = "append";
/**
*Overwrite mode
*/
public static final String WRITE_MODE_OVERWRITE = "overwrite";
/**
*New creation mode (error if there is a file)
*/
public static final String WRITE_MODE_NEW = "new";
A write method using this mode would have the following signature:
public void write(String data, String mode)
Both the first and second arguments are String
and it is difficult to distinguish without checking the argument name.
Also, if mode
is a string that is not supported because of String, it will be necessary to consider it.
For example, by using an enumeration type or Mode class, mistakes such as passing the original data as the second argument will not occur.
enum WriteMode {
/**
*Addendum mode
*/
APPEND,
/**
*Overwrite mode
*/
OVERWRITE,
/**
*New mode
*/
NEW;
}
In this case, the signature would look like this:
public void write(String data, WriteMode mode)
It's a matter of course when you look at this alone, but when you code while verifying, there are still codes that say "Well, for the time being", or such code is included due to omission of refactoring. I want to be careful with my own caution as it may end up.
Recommended Posts