Please stop the code comment
"Clean code should be like a well-written prose" - Robert C. Martin
A common problem with bad code is that there are many comments. This is the most obvious sign of messy source code.
The goal of every programmer should be to write clean and expressive code to avoid code comments. The purpose of each variable, function, and class should be implicit in its name and structure.
When others read your code, they shouldn't read comments to understand what your code is doing. Well-named classes and functions should guide readers through your code like a well-written novel. When readers see a new class or function, they should not be confused and difficult to understand what they see inside.
Remember that developers rarely spend their working hours writing code, and they spend much more time reading and understanding code.
Comment mask error
Naming in code is very important. You should spend a lot of effort to name each piece of code accurately and accurately so that other developers can understand your code.
// Find employees by statusList<Employee> find(Status status) { ... }
In this example, the name find is not enough to describe, so the author of this function needs to leave a descriptive comment describing the function's function. When we see the find function called from another module, its function is a mystery. What did it discover? What exactly does it mean? Did it return what it found? How to find what it found? As Uncle Bob said in his book Clean Code, if you need to write comments, you can't express your true intentions through code.
We do not want to check the comments above each function to understand what it does.
List<Employee> getEmployeesByStatus(Status status) { ... }
It is now obvious that the specific function of this function can be seen, which makes the comments redundant. This reminds me of the next way to poor comments.
Redundant comments
This messes up your code and is completely unnecessary.
//This function sends an emailvoid sendEmail() { ... } //This function sends an emailpublic class Employee { ... } / ** * @param title CDTitle * @paramauthorCD的author * @param track CDNumber of tracks on * / public void addCd(String title, String author, int tracks) { ... }
In most cases, forced redundancy. Many companies require this in every feature and category. If your boss asks to do so, please don't.
The degree of abstraction of error
If you have a long feature or need to document which part of the code does what, then you may have violated these rules:
1. Functions should do one thing.
2. The function should be very small.
Here is an example
//This function calculates the price and compares it with sales//Promotion, check whether the price is valid, then//Send promotional emails to userspublic void doSomeThings(){ // Calculate the price... ... ... //Introduce the calculated price and promotion activities... ... ... // Check whether the calculated price is valid... ... ... //Send promotional information to users... ... ... }
When you successfully encapsulate each part of the logic into a separate function, the code should behave like its description without commenting.
Refactoring is as follows:
public void sendPromotionEmailToUsers(){ calculatePrices(); compareCalculatedPricesWithSalesPromotions(); checkIfCalculatedPricesAreValid(); sendPromotionEmail(); }
Instead of commenting every part of the code, each logical block should be well encapsulated in its own function.
First, this improvesreadability. Each code block does not have to be read line by line. We can simply read the helper function name and understand what it does. If we want to understand more details inside each function, we can look at the specific implementation.
Secondly, it improvesTestability. In the example above, we can perform unit tests for each function individually. It is difficult to test each part of the larger function sendPromotionEmailToUsers() without encapsulating these individual functions. Functions that perform multiple functions are difficult to test.
Finally, it improvesReconfigurability. By encapsulating each part of the logic into its own function, it is easier to change and maintain in the future, and functions of individual functions are isolated to change only the behavior of that function. When we use long functions of local variables to persist throughout the function, it is difficult to reconstruct the function without causing changes elsewhere due to tight coupling of the function.
Commented out code
Commented out code should be considered a roadkill. Don't look at it, don't smell it, don't ask where it comes from, just get rid of it. The longer you keep it, the longer the rest of the code smells...
/ * public void oldFunction(){ noOneRemembersWhyIAmHere(); tryToUnCommentMe(); iWillProbablyCauseABuildFailure(); HAHAHA(); } * /
Even if you delete it, you won’t delete it, and others won’t dare to delete it. If you need it in the future, you can always check the version control system because you must have used VCS, right? (If it's not like I didn't say it)
TODO Comments
Don't write TODO comments, not just...did it do it? Most of the time these comments are forgotten and may become irrelevant or wrong later on. When another programmer sees the TODO comment later, how do they know if this is needed?
But occasionally TODO comments are good if you are waiting for another teammate's merge (usually not too long). Just do it until you can fix it and submit it.
"When you feel the need to write comments, first try to refactor the code so that any comments become redundant." - Martin Fowler
Commented lies
When Jimmy comments on the new features he wrote, he thinks he is helping any future developer who sees his code. In fact, what he is really doing is setting a trap. His notes may be a lie (without pun intended) dormant for months or years without being touched, just waiting to become a nasty trap. Then one day, in one of hundreds of refactoring and demand changes, his comments failed from some distant modules, but were still leading countless buyers incorrectly.
When you change a line of code, how do you know if the code you change will invalidate comments elsewhere? There is no way to know
public class User { ... //It contains the user's first and last nameString name; ... }
Then the requirements change, and they want to split the names into firstName and lastName.
public class User { ... // It contains the user's first and last nameString firstName; String lastName; ... }
The comment is now wrong. You can update the comments to reflect the changes, but do you really want to manually maintain all comments after each change? You are a developer, not a document.
But this comment is easy to notice and has no problem to change. But it is difficult for you to guarantee that other places in the program will also comment that the name of this parameter is the user's first and last name. Changing a small piece of code may invalidate many code comments.
Let's look at another example:
//Dispose employees according to statusvoid processEmployees(){ ... List < Employee > employees = findEmployees(statusList); ... } //This will look for Employees by status listList < Employee > findEmployees(List < String > statusList){ ... }
Then someone was asked to change the function findEmployees so that the employees can be found by name list instead of status list.
//Dispose employees according to statusvoid processEmployees(){ ... List < Employee > employees = findEmployees(statusList); ... } //This will look for Employees by status listList < Employee > findEmployees(List < String > nameList){ ... }
First, the above comment findEmployees has expired and therefore needs to be changed. No problem, right? Wrong.
The comment above processEmployees has also expired and therefore needs to be changed as well. How many other comments have been changed to invalid by this small refactoring? How many comment lies did this change create in the source code?
Alternatives:
void processEmployees(){ ... List < Employee > employees = findEmployeesByName(nameList); ... } List < Employee > findEmployeesByName(List < Name > nameList){ ... }
If you name your function accurately and accurately, there is no need for comments and you won't spread lies in your code.
"The code never lie, the comments will." - Ron Jeffries
When do I need comments
I know a lot of developers are dead hard supporters of code comments, for them I have to admit that sometimes comments are OK. But every time you write a paragraph, you should have sufficient reasons.
Complex expressions
If you have complex SQL or regular expression statements, please proceed to writing comments. It can be difficult to express statements like this cleanly in the code. Adding comments on these expressions can help other developers better understand your code.
// Format matching kk:mm:ss EEE,MMM dd,yyyyPattern timePattern = ("\\d*:\\d*:\\d* \\w*, \\w*, \\d*, \\d*");
Comment warning
If you need to warn other developers about possible bugs in this code, you can leave a comment near this code. These comments can act as a precursor to mysterious behavior in your code and add value to your code.
Intent clarification
If you really have a name, you have to be responsible for your inability to write expressive code and write comments to express your intentions.
If you have to write comments, make sure it is local. Non-local comments that are far from their quotes are doomed to fail and turn into lies. Comments referring to functions or variables should be directly above them. The warning comment can be above or next to the code it references. If your IDE supports comment highlighting, make your warning comment stand out from the rest of your code.
at last
I've built my feelings about code comments. I despise them, but I know sometimes they need it.
So, please stop writing so many comments.
This article is a statement by the author on Twitter by Brian Norland, a foreign god, who deeply believed that it was translated and modified to share it. I hope my code will be as elegant as prose in the future.