[The Beauty of Design Patterns Design Principles and Thoughts: Specification and Refactoring] 31 | Theory Five: 20 Programming Specifications that Allow You to Improve Code Quality Quickly (Part 1)

We have talked about a lot of design principles before, and we will talk about a lot of design patterns later. Making good use of them can effectively improve the code quality. However, the reasonable application of this knowledge is very dependent on personal experience, and sometimes it will backfire if it is not used well. The coding standards we are going to talk about next are just the opposite. Most of the coding standards are simple and clear, and in terms of code details, the quality can be improved immediately. In addition, we also mentioned earlier that continuous low-level and small-scale refactoring relies on coding standards, which is also an effective means to improve code readability.

Many books have already talked about coding standards and how to write readable code. I also recommended several classic books in the previous meal. However, here I summarize and list 20 coding standards that I personally think are the best to use based on my own development experience. Mastering these 20 coding standards can help you improve the code quality most quickly. Because there is a lot of content, I divided it into three lessons to explain the three parts of the coding specification: naming and comments (Naming and Comments), code style (Code Style) and programming skills (Coding Tips).

name

As big as project name, module name, package name, externally exposed interface, as small as class name, function name, variable name, and parameter name, as long as we are doing development, we cannot escape the "naming" level. The quality of the naming is very important to the readability of the code, and it can even be said to play a decisive role. In addition, the naming ability also reflects the basic programming literacy of a programmer. This is why I put "naming" first to explain.

Choosing a particularly appropriate name can be quite a challenge, even for native English-speaking programmers. And for us non-native English programmers, it is even more difficult to come up with a name that can accurately express the meaning.

In fact, the matter of naming is not difficult, the key is to see whether you pay attention to it and whether you are willing to spend time. For naming with a relatively large scope of influence, such as package names, interfaces, and class names, we must repeatedly consider and deliberate. When you really can't think of a good name, you can go to GitHub and use relevant keywords to associate and search to see how similar codes are named.

How should it be named? Is there any standard for good naming? Next, I will explain my experience from 4 points.

1. What is the most suitable length for naming?

In past teams and projects, I have encountered two completely different types of colleagues. There is a kind of colleague who likes to use very long naming methods, and feels that the naming must be accurate and expressive, even if it is longer, it does not matter. Therefore, in the projects of this kind of colleagues, the class names and function names are very long. Another kind of colleagues like to use short naming methods, and use abbreviations as much as possible. Therefore, the project is full of names containing various abbreviations. Which of these two naming methods do you think is more recommended?

In my opinion, although long names can contain more information and express intent more accurately and intuitively, if the names of functions and variables are very long, the statements composed of them will be very long. When the length of the code column is limited, it will often happen that a statement is divided into two lines, which actually affects the readability of the code.

In fact, the shorter the naming, the better, if it is enough to express its meaning. However, in most cases, short names are not as expressive as long ones. Therefore, many books or articles do not recommend using abbreviations when naming. For some default and well-known words, I recommend using abbreviations. In this way, on the one hand, the name can be shortened, and on the other hand, it does not affect reading comprehension. For example, sec means second, str means string, num means number, and doc means document. In addition, for variables with relatively small scope, we can use relatively short names, such as temporary variables in some functions. On the contrary, for a class name with a relatively large scope, I recommend using a long naming method.

In short, one of the principles of naming is to aim at expressing the meaning accurately. However, for the code writers, they are very clear about the logic of the code, and always feel that any name can be used to express their ideas. In fact, for colleagues who are not familiar with your code, they may not think so. Therefore, when naming, we must learn to empathize, assuming that we are not familiar with the code, and consider whether the naming is intuitive enough from the perspective of the code reader.

2. Use context to simplify naming

Let's look at a simple example first.

public class User {
  private String userName;
  private String userPassword;
  private String userAvatarUrl;
  //...
}

In the context of the User class, we did not repeatedly add the prefix word "user" to the naming of the member variables, but directly named them name, password, and avatarUrl. When using these attributes, we can use the context of the object, and the meaning is clear enough. The specific code is as follows:

User user = new User();
user.getName(); // 借助 user 对象这个上下文

In addition to classes, function parameters can also use the function context to simplify naming. Regarding this point, I gave the following example, you can understand it at a glance, so I won't be too long-winded.

public void uploadUserAvatarImageToAliyun(String userAvatarImageUri);
// 利用上下文简化为:
public void uploadUserAvatarImageToAliyun(String imageUri);

3. Make the name readable and searchable

First, let's look at what is named readable. Let me explain first, the "readable" I am talking about here means not to use some particularly uncommon and difficult-to-pronounce English words to name.

I have participated in two projects in the past, one is called plateaux and the other is called eyrie. From the beginning to the end of the project, few people can call the names of these two projects correctly. When communicating, whenever someone mentioned the names of these two projects, they would freeze awkwardly. Although we do not reject some unique naming methods, at least most people can know how to read them at a glance. For example, a project I participated in at Google is called inkstone. Although you may not know what it means, you can basically read it without affecting communication. This is a relatively good project name.

Let's talk about naming searchable again. When we write code in the IDE, we often use the "keyword association" method to automatically complete and search. For example, if you type a certain object ".get", you want the IDE to return all the methods starting with get of this object. For another example, search for array-related classes in the JDK by entering "Array" in the IDE search box. Therefore, when we name it, it is best to conform to the naming habits of the entire project.

Everyone uses "selectXXX" to express queries, so you don't need to use "queryXXX"; everyone uses "insertXXX" to indicate inserting a piece of data, so you don't need to use "addXXX". A unified protocol is very important and can reduce a lot of unnecessary troubles .

4. How to name interfaces and abstract classes?

For the naming of interfaces, there are generally two common ways. One is to add the prefix "I" to indicate an Interface. For example, IUserService, the corresponding implementation class is named UserService. The other is to add no prefix, such as UserService, and add the suffix "Impl" to the corresponding implementation class, such as UserServiceImpl.
For the naming of abstract classes, there are also two ways, one is with the prefix "Abstract", such as AbstractConfiguration; the other is without the prefix "Abstract". In fact, for interfaces and abstract classes, you can choose any naming method, as long as they can be unified in the project.

note

Naming is important, and comments are as important as naming. Many books believe that good naming can completely replace comments. If comments are needed, it means that the naming is not good enough, and you need to work on naming, not adding comments. In fact, I personally feel that such a view is a bit too extreme. No matter how good the naming is, after all, there is a length limit, and it is impossible to be detailed enough. At this time, comments are a good supplement.

1. What should be written in the comment?

The purpose of comments is to make the code easier to understand. As long as the content meets this requirement, you can write it in the comment. To sum up, the content of the annotation mainly includes three aspects: what to do, why, and how to do it. Let me give you an example to explain it in detail.

/**
* (what) Bean factory to create beans. 
* 
* (why) The class likes Spring IOC framework, but is more lightweight. 
*
* (how) Create objects from different sources sequentially:
* user specified object > SPI > configuration > default object.
*/
public class BeansFactory {
  // ...
}

Some people think that comments are to provide some additional information that the code does not have, so don't write "what to do, how to do it", both of which can be reflected in the code, just write clearly "why", indicating the design intent of the code That's it. Personally, I don't particularly agree with this point of view, mainly for the following three reasons.

  • Comments carry more information than code

The main purpose of naming is to explain "what to do". For example, void increaseWalletAvailableBalance(BigDecimal amount) indicates that this function is used to increase the available balance of the wallet, and boolean isValidatedPassword indicates that this variable is used to identify whether the password is valid. Well-named functions and variables can indeed eliminate the need to explain what it does in comments. However, for a class, it contains a lot of information, and a simple naming is not comprehensive enough. At this time, it makes sense to write "what to do" in the comments.

  • Comments serve as a summary and documentation

There are no secrets under the code. Reading the code can clearly know the "how to do it" of the code, that is, how to realize the code, so don't you need to write "how to do it" in the comments? It can actually be written too. In the comments, we can write some summary instructions and explanations for special cases about the specific code implementation ideas. In this way, people who read the code can roughly understand the implementation idea of ​​the code through comments, and it will be easier to read.

In fact, for some more complex classes or interfaces, we may also need to write clearly "how to use" in the comments, and give some simple quick start examples, so that users can quickly know what to do without reading the code. how to use.

  • Some concluding comments to make the code structure clearer

For code with complex logic or long function, if it is not easy to refine or split into small function calls, then we can use summary comments to make the code structure clearer and more organized.

public boolean isValidPasword(String password) {
  // check if password is null or empty
  if (StringUtils.isBlank(password)) {
    return false;
  }
  // check if the length of password is between 4 and 64
  int length = password.length();
  if (length < 4 || length > 64) {
    return false;
  }
  
  // check if password contains only lowercase characters
  if (!StringUtils.isAllLowerCase(password)) {
    return false;
  }
    
  // check if password contains only a~z,0~9,dot
  for (int i = 0; i < length; ++i) {
    char c = password.charAt(i);
    if (!(c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.') {
      return false;
    }
  }
  return true;
}

2. Is the more comments the better?

There are problems with too many comments and too few. Too many may mean that the code is not readable enough and needs to be supplemented by writing a lot of comments. In addition, too many comments will interfere with the reading of the code itself. Moreover, the maintenance cost in the later period is relatively high. Sometimes the code is changed, and the comments are forgotten to be modified synchronously, which will confuse the code readers even more. Of course, if there is no line of comments in the code, it can only show that the programmer is lazy. We should properly supervise and let him pay attention to adding some necessary comments.

According to my experience, comments must be written for classes and functions, and they must be written as comprehensively and detailedly as possible, while comments inside functions are relatively less, generally relying on good naming, refined functions, explanatory variables, Summarizing comments to improve code readability.

Summary

Well, that's all for today's content. Let's summarize and review the key content you need to master.

1. About naming

  • The key to naming is to be able to express the meaning accurately. For the naming of different scopes, we can choose different lengths appropriately. For variables with small scope (such as temporary variables), you can choose a shorter naming method appropriately. In addition, some familiar abbreviations can also be used in naming.
  • We can use class information to simplify the naming of attributes and functions, and use function information to simplify the naming of function parameters.
  • Names should be readable and searchable. Don't use uncommon, difficult-to-pronounce English words to name. In addition, the naming must conform to the unified specification of the project, and do not use counter-intuitive naming.
  • There are two naming methods for interfaces: one is to have the prefix "I" in the interface; the other is to have the suffix "Impl" in the implementation class of the interface. For the naming of abstract classes, there are also two ways, one is with the prefix "Abstract", and the other is without the prefix. Both naming methods are acceptable, the key is to be unified in the project.

2. About comments

  • The purpose of comments is to make the code easier to understand. As long as the content meets this requirement, you can write it in the comment. To sum up, the content of the annotation mainly includes three aspects: what to do, why, and how to do it. For some complex classes and interfaces, we may also need to write "how to use".
  • The annotation itself has a certain maintenance cost, so the more the better. Classes and functions must write comments, and they must be written as comprehensively and detailedly as possible, while there are relatively few comments inside functions. Generally, good naming, refined functions, explanatory variables, and summary comments are used to improve code flexibility. readability.

class disscussion

  • When we talked about "using concluding comments to make the code structure clearer", we gave an example of the isValidPassword() function. In terms of code readability, what can be further optimized for this function?
  • Regarding the notes, do you recommend writing in English or Chinese? What is the reason?

Welcome to write down your answers in the message area, communicate and share with your classmates. If you gain something, you are welcome to share this article with your friends.

Guess you like

Origin blog.csdn.net/qq_32907491/article/details/129891049