21 Your Code Is Written for Whom

21 Who are you writing your code for? #

Hello, I am Zheng Ye.

When it comes to the topic of “communication feedback,” I plan to start with the code because, after all, we programmers communicate with the machine through code.

Writing code is the responsibility of every programmer, and programmers all know that they should write good code. But what does it mean to write good code? Everyone has their own understanding.

Writing Maintainable Code #

Programmers who are new to programming may think that code that can implement functionality is good code. This stage mainly focuses on learning the basic skills, such as various algorithms, data structures, typical processing techniques, commonly used frameworks, and so on.

After a period of work, most of the code required for daily work becomes effortless for you. Especially with the booming development of search and question-and-answer websites, you no longer need to memorize many common code patterns like I did when I first entered the workplace. Now, you can simply search for it and find the answer.

Furthermore, programmers who pursue excellence will realize that simply implementing functionality is not enough, and it is also necessary to write maintainable code. Therefore, such programmers will look for some classic books to read.

My learning in this area started with a book called “The Practice of Programming” by Brian Kernighan and Rob Pike. Both of them are from the famous Bell Labs and have participated in the development of Unix.

Writing maintainable code is not difficult; it also has its own methods. Today, we will delve into the simplest thing in writing code and analyze how to write maintainable code: naming.

The Challenge of Naming #

In computer science, there are only two hard problems: cache invalidation and naming. – Phil Karlton

This is a classic saying that is widely circulated in the industry. No matter which book on coding style you read, naming will always be one of the first topics discussed.

When you first start writing code, someone will probably tell you not to use variables like a, b, c because they have no meaning. When you enter the workplace, someone will hand you a coding standard and tell you that it must be followed.

Regardless, you know that naming is important, but in your mind, what does a qualified name look like?

You may know that naming should follow coding conventions, such as camelCase for Java style and using all capital letters for constants.

However, these coding conventions mainly provide formatting requirements. In my opinion, this is just the minimum requirement and should not be the pursuit of programmers, because many of these coding conventions can now be scanned by static analysis tools.

Our discussion should start from the meaning of names. As programmers, most of us understand why we should avoid meaningless names, but everyone has a different understanding of what constitutes a meaningful name.

A simple criterion for judging whether a name is good enough is to consider how much extra explanation is needed when explaining the code to someone.

For example, in a code review, you may come across a situation like this:

Reviewer: What is the purpose of this variable named “map”? - Programmer: It is used to store account information, where the keys are account IDs and the values are corresponding account information. - Reviewer: Then why not just name it “accounts”?

Do you understand what the reviewer’s suggestion means? If you can’t immediately realize it, you might feel the same frustration as the programmer: What’s wrong with naming this variable “map” since it is just a map?

Naming variables actually involves an important question: Who is the code written for?

Who is Code Written for? #

Anyone can write code that a computer can understand. Good programmers write code that humans can understand. - Martin Fowler

Code is indeed an important means of communication between programmers and machines. However, machines are straightforward. The code you write must comply with certain rules, and this is already ensured by the compiler. If your code does not comply with the rules, you can’t even run it.

So as long as your code complies with the language rules, the machine will recognize it. It’s not difficult to make the machine recognize your code. No matter how strange your code is, it will be recognized. There are even dedicated contests for writing chaotic code in the industry. For example, the well-known IOCCC (The International Obfuscated C Code Contest).

However, our purpose in writing code is to communicate with people, because we need to collaborate with others in a team.

To communicate with people, you need to write code using a language and style that people can understand. People are different from machines. People not only need to understand the language rules, but also need to incorporate the business context into the code. This is because people’s goal is not just to execute the code, but to comprehend, expand, and maintain the code.

People are responsible for connecting business problems with machine execution. Without the business context, it is impossible to write good code.

In our previous article “Why the World and Your Understanding Are Different,” we talked about the importance of the encoder when outputting information during communication. The encoder is the key to ensuring the accuracy of information output.

Many programmers are accustomed to expressing themselves using the language of computers. For example, in the example mentioned earlier, the name “map” is a name of a data structure, which is geared towards computers. However, the reviewer suggested changing the variable name to “accounts,” which is a business name.

Although it’s just a simple name change, in terms of understanding, it represents a huge leap. It reduces the gap that others need to fill in order to understand this piece of code, thereby naturally improving work efficiency.

Writing Code in Business Language #

When writing code, it is best to use business language as much as possible, as it will help you change your mindset. Let’s look at another example using the most common e-commerce ordering process.

Intuitively, we would create an order class called Order. What should be included in this class?

Firstly, it is reasonable to include the product information in this class. Secondly, since it is an e-commerce order, there may be delivery information, which makes sense. Additionally, when purchasing items, we need to choose a payment method, so payment information should also be included.

With this in mind, you will notice that the information in this order class keeps growing. Membership information might need to be added, as well as discount information.

As the person responsible for maintaining this code, you will soon find yourself dealing with an increasingly large class. Every modification will have to pass through you. Without realizing it, you become overwhelmed.

From the perspective of simply making the code run, this is almost an unsolvable problem. We feel uncomfortable, but don’t have a good solution, so we just make the necessary changes.

However, if we adopt a business perspective, we would ask the question, “Are all these pieces of information logical to be stored in an ‘Order’?”

By communicating with the business staff, asking when and where these pieces of information are actually used, you will realize that the product information is mainly used during the order process, delivery information is important for logistics, and payment information is only needed during the payment process.

With this information, you will understand one thing: even though we are using the concept of an “order,” in different scenarios, different pieces of information are required.

Therefore, a better approach is to break down this concept of an “order” into different types: a transaction order, a logistics order, and a payment order. The difficulty we originally encountered was due to our lack of business knowledge, which led us to use the generic term “order” to cover various scenarios.

If you work for an e-commerce platform, you may already be familiar with these different concepts. However, in reality, similar mistakes can be found in many codebases.

Let’s take another example: in many systems, the concept of a “user” is heavily used, with a lot of information being stored in the user object. However, in different contexts, the term “user” should represent different entities. For example, in project management software, it should represent project administrators and project members, whereas in lending scenarios, it should represent borrowers and lenders.

To differentiate these concepts properly, you need to have a deep understanding of the business language. To avoid confusion, the best approach is to reflect these concepts in your code and give them appropriate names. This requires using the same language as the business staff.

If you are familiar with Domain Driven Design (DDD), you may have already recognized that what I am describing here is essentially DDD. Breaking down different concepts is the role of Bounded Context, and using business language as much as possible in the code is the role of Ubiquitous Language.

Therefore, good naming requires a thorough understanding of the business knowledge. Unfortunately, this is not usually a strong point for programmers and requires additional learning. However, it is a prerequisite for writing good code. Now that you understand this, you realize that choosing a good name is not an easy task.

Summary #

Code is the bridge of communication between programmers and machines. Writing good code is the pursuit of every programmer. As a professional programmer, you should not only focus on implementing functionality, but also strive for maintainable code. If you want to learn in detail how to write good code, I recommend reading “Clean Code” by Robert Martin. This book covers almost every aspect of writing good code.

Naming is the foundation of writing programs and is also a threshold for programmers to transition from amateurs to professionals. Based on naming, I will explain the path to improving code quality. The initial level is writing code that can run, followed by writing code that conforms to coding standards.

For naming, the most basic understanding is to avoid using meaningless names and follow coding conventions. However, whether a name is good enough depends on whether it requires additional explanation. Many programmers are accustomed to using names based on implementation, such as using the names of data structures.

To further improve, the code should be written in a way that can be understood by humans. Because the most important function of code is to serve as a bridge of communication between people, it is important to use names that reduce the barrier of understanding for others.

In fact, one of the reasons why many of our poorly written programs exist is because of incorrect naming, which confuses various concepts together. To come up with good names, you need to learn how to write code using business language and gain as much domain knowledge as possible to incorporate domain-specific names into your code.

If there is only one thing you can remember from today’s content, please remember: Write code using business language.

Finally, I would like you to think about what other factors are especially important to you in order to write good code. Feel free to share your thoughts in the comments section.

Thank you for reading. If you found this article helpful, please consider sharing it with your friends.