preface

You might have written a lot of things like

int a,b,c
int [] arrays=new int arrays[10];
if((numbers > 10 && flag == 'true') || flag =='false')
Copy the code

This kind of code, for our own practice programming or solving an algorithm problem, of course, no problem. But if it is in a project, especially dozens or hundreds of people maintain the project for several years, but also use this writing method, pour out their unconstrained talent, to ensure that the leader does not kill you oh.

So, there have been many summaries of code cleanliness and readability since ancient times, such as this book clean Code, the Chinese name is Called Clean Code, and today, we will take a look.

 

named

Naming thoughts

The first is naming, naming can be said to be the basis of all procedures, if three words to describe that is – “meaningful”.

You have to make sure that when a person sees your name, they know what the variable/function does.

Take a look at this code:

public List<int[]> getThem() {
  List<int[]> list1 = new ArrayList<int[]>();
  for (int[] x : theList)
    if (x[0] == 4)
      list1.add(x);
  return list1;
}
Copy the code

This code is very concise, but very vague, we don’t know exactly what theList is, why x==4 as a judgment, and what is list1?

Now let’s change it:

public List<int[]> getFlaggedCells() { List<int[]> flaggedCells = new ArrayList<int[]>(); for (int[] cell : gameBoard) if (cell[STATUS_VALUE] == FLAGGED) flaggedCells.add(cell); return flaggedCells; Copy the codeCopy the code

FlaggedCells is a cell in the gameBoard, which is a gameBoard, and flaggedCells are each cell in the gameBoard. The if statement determines whether each grid has been clicked, and if so, adds it to flaggedCells. We obviously know what it’s trying to do — collect the grid that the player clicked on and return it.

The number inside each array represents the state of the cell. However, the cell does not need that many states, and this causes the array to be redefined each time the state is used. The state is an attribute of the cell. It is perfectly possible to define a cell class that encapsulates its state.

public List<Cell> getFlaggedCells() {
  	List<Cell> flaggedCells = new ArrayList<Cell>();
    for (Cell cell : gameBoard)
    if (cell.isFlagged())
    flaggedCells.add(cell);
    return flaggedCells;
}
Copy the code

If you take a Cell out of a gameBoard and put it in flaggedCells, does this code feel natural?

Naming conventions

From the above examples, you should understand that when writing a project, the underlying structures such as arrays, linked lists, and dictionaries should be wrapped in classes such as User, Cell, and Address. You can use these classes directly when using them. This is a kind of big picture thinking. I’m sure you’re familiar with Hungarian hump naming, but I want to emphasize two more places here.

  • A class, as an object, needs a noun or noun phrase. This is true for gameBoard and Ueser. Don’t use vague nouns like Data, which can be subdivided into UserData, MoneyData, etc. Class names are combinations of nouns that begin with a capital letter.
  • Method name as a specific director executives, of course, is to use a verb or a verb phrase, also note that don’t use fuzzy verb, and is not the same as above, the ways to solve fuzzy noun is to add a noun, and the ways to solve fuzzy verb is “in a more precise verb” getInformation, for example, is bad, Because GET is too big, is your information pulled or clone? Is it passively received or is it actively taken? The word Information is also vague, so it can be broken down to fetchUserData directly — fetchUserData, upload new data and fetchUserData — uploadAndfetchUserData. It’s not that you can’t use get, it’s that if you have a better choice, try to use a more precise verb. Note that the first letter of the method name is lowercase.

function

The first principle

Short,

If there’s a second rule, it’s short.

How short? Maybe 20 or 30 lines at the most,

So I want a function that only does one thing,

What does it mean to only do one thing?

In the case of processing data, when we say [processing user data] is one thing, you can also say that you do three things:

  1. Take the data
  2. Process the data
  3. Return the data

Of course, this example is a bit cynical, but it reflects the reality that the logic of code is often intertwined. Where is the boundary of a thing?

This varies from person to person, so I can only suggest the method in the book.

  1. At the same level of abstraction the thing that we did at the same level of abstraction is one thing, but if we do one more thing — save the user data, obviously, it’s still one thing, but if we do one more thing — get the vehicle data, obviously, it’s another abstraction.
  2. Segmentation judgment and processing this good understanding, is legislative and judicial segmentation, such as: if (set(“username”, “uncleBob “))… Copying code is confusing. Does it mean that uncleBob returns true if it successfully assigns to username? Or if username is null then uncleBob is assigned to it? Is username a property or just happens to be a string called username? Just guess. If (attributeExists(“username”)) {setAttribute(“username”, “uncleBob “); . }} if there is a username attribute, the assignment is clear, that is, the judgment and processing should be separated.

You might say that statements like if, while, and switch take more than a dozen lines.

First of all, this principle is not an iron law, even if it is too long.

Second, for these statements, it is possible to encapsulate the logic inside, such as:

public static String renderPageWithSetupsAndTeardowns(
  PageData pageData, boolean isSuite) throws Exception {
  if (isTestPage(pageData))
    includeSetupAndTeardownPages(pageData, isSuite);  return pageData.getHtml();
}
Copy the code

If statements made after a includeSetupAndTeardownPages thing, not only greatly enhances the readability, and the code short a lot.

About the parameters

When you look at the JDK source code or the Android source code, you’ll see that they make calls a lot, especially the method overloading of the same name, in the Algorithm book, for example, on quicksort:

public static void quickSort(int [] arrays){ quickSort(arrays,0,arrays.length-1); }private static void quickSort(int [] arrays,int left,int right){ ... }Copy the code

When I first got into it, I thought it was nice but cumbersome, and as I got more experience, it was a good programming habit.

First of all, for the user, if he wants to fast-sort, all he wants to pass is the array, and the left and right boundaries are included, why do you want him to pass more parameters? And the first method uses public, which means it’s exposed to the user.

Second, the second method is called in the first method, which is private and saves a lot of trouble.

So, the more business logic you have, the more you have to write code with fewer arguments. If you have to have a lot of arguments, then wrap it up in a private function. You let the user have a hundred arguments.

The experience of using Apple and wechat is a representative of the ultimate implementation of this philosophy.

annotation

The best comments are the code itself.

Use as few comments as possible to explain what the code can explain. If there are too many comments, the code is bad…

But there are some areas where you need to write code.

location

It is best to write it at the top of the method and not insert it into the actual code, such as equals (String).

 ... 
 * @see  #compareTo(String)
 * @see  #equalsIgnoreCase(String)
 */public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }    if (anObject instanceof String) {
        String anotherString = (String)anObject;        int n = length();        if (n == anotherString.length()) {
            int i = 0;
            while (n-- != 0) {
                if (charAt(i) != anotherString.charAt(i))
                        return false;
                i++;            }            return true;
        }    }    return false;
}
Copy the code

Warning note

Write some warning code here so that the next person will be taken seriously.

//When I wrote this, only God and I understood what I was doing
//Now, God only knows
Copy the code

In short, the following code must be useful, but I don’t understand it, you don’t touch it

I saw something like this on Zhihu.

// If this is wrong, you installed a 360 security guard on the machine. Trust me, I thought it was a joke, but it turned out to be good. This one was left to me. // If you have any questions about the service, you can ask XXX. He wrote this paragraph. I wrote this during my transition, selling out a colleague who was still there. // After the execution is successful, send a notification message and comment out the phone number after it is stable. It is written dead.Copy the code

The level of these people how to say, but for posterity or intentions.

TODO comment

I’m not going to do that. It’s very common.


Having looked at the useful comments, let’s take a look at the useless ones

redundant

// Utility method that returns when this.closed is true. Throws an exception // if the timeout is reached. public synchronized void waitForClose(final long timeoutMillis) throws Exception { if(! closed) { wait(timeoutMillis); if(! closed) throw new Exception("MockResponseSender could not be closed"); }}Copy the code

It’s just describing what the code does again, and it doesn’t make any sense.

Code that is commented out

InputStreamResponse response = new InputStreamResponse(); response.setBody(formatter.getResultStream(), formatter.getByteCount()); // InputStream resultsStream = formatter.getResultStream(); // StreamReader reader = new StreamReader(resultsStream); // response.setContent(reader.read(formatter.getByteCount()));Copy the code

I believe that many people have such behavior, in their own writing algorithm when used to test a test without any problems, but for the later, how should he do?

He must have thought: might it be useful? That’s why I wrote it before.

But he couldn’t read it or didn’t feel the need to read it, so he left it, and it grew and grew, and eventually became the legendary heirloom code.

Not the heart

Comments to be clear, if the comments have to write comments to explain, there is no point.

Like this one down here, why use 200?

/*
* start with an array that is big enough to hold all the pixels
* (plus filter bytes), and an extra 200 bytes for header info
*/
this.pngBytes = new byte[((this.width + 1) * this.height * 3) + 200];
Copy the code

 

summary

For most people, named functions and comments are basically the main parts of the program. If you can handle these three things well, you can write very good code. When the leader sees your submission and sees such elegant code, I think he will also feel a kind of enjoyment, just like poetry.