Straight to the point: Clean code

Brenno de Moura
7 min readJun 1, 2023

As part of my Individual Development Program (IDP), I have been dedicated to studying the theory behind the knowledge I have acquired throughout my career as an Swift developer. This article details my studies based on the Clean Code book.

First Impressions

After careful consideration of how to start this article, I concluded that it would be better to maintain a professional approach and focus less on the theory of the book. I write this because the author begins by explaining the importance of clean code and how it should be applied in practice. Clean code should be seen as a philosophy and an individual art, in which concepts are applied to projects to achieve excellence and quality.

The term “clean code” should be interpreted as “I write clean code. It is easy to read, has few abstractions, and follows a simple and coherent logical flow.” This became clearer when the author compared writing code to writing an essay. We are not just talking about programming techniques, but also about the textual quality of the code. Therefore, clean code is not just a technique or tool, but a way to label code as readable and well-written textually.

It is important to note that when I use the word textually, I refer to the characters and spaces written in the code.

From this point, we can discuss the main topics addressed by the author in the book on clean code. Although it can be applied to projects that benefit groups, the approach is highly individual, and the book’s content should be absorbed by each programmer based on their own experience.

If you value writing cohesive and simple code, you will certainly appreciate this book.

Comments

C1: Inappropriate Information

The use of comments is a common practice in programming and can be a useful tool to make code more readable and understandable. However, it is important that comments are relevant and useful to those who read the code.

Following guidelines to include only relevant technical information and avoiding version control information or other metadata can help maintain accurate and concise comments. Additionally, avoiding irrelevant or outdated information can help prevent confusion and make the code easier to understand and maintain.

The following example contains version control information and the author’s name, which can now be easily managed through version control systems like Git. To keep only relevant information, we can refactor the code and remove these unnecessary snippets, like this:

C2: Obsolete comment

Keeping comments up-to-date is essential for the clarity and understanding of the code. Outdated comments can generate confusion and errors, so it is important to update them or delete them. It is recommended to keep comments precise and relevant so that important information is clear to all involved.

During the code implementation, it was identified that the user would have a property called “type”, whose value “admin” would be used to identify the administrator role. Including this information as a comment in the function can be problematic because the comment will become outdated if the “admin” key is renamed or the “type” property is changed.

If developers do not update both the code and the comment, it is likely that the comment will become obsolete, which can lead to errors and bugs in the interpretation of the code. Therefore, it is essential to avoid including specific implementation details in a code comment unless it is absolutely necessary.

C3: Redundant comments

According to the author, comments should go beyond obvious evidence in the code and function signature and explain the reasoning behind actions. This makes the code easier to understand and maintain in collaborative and long-term programming projects, making comments important tools for effective communication.

Functions

F1: Excessive parameters

Limiting the number of parameters in functions, preferably up to three, is beneficial to simplify the code. However, it is important to be flexible with this recommendation to ensure efficiency and accuracy in specific cases. Evaluating the best approach to take is essential.

F2: Output parameters

Avoiding the use of output parameters is an important recommendation in function or method construction. Instead, the state of the object should be directly modified or the expected result should be returned as the function’s return value, making the code more readable and understandable for other developers in the future.

G30: Functions should do one thing only

Defended by the author as one of the best programming practices, the Single Responsibility Principle seeks to ensure that each function or code module has only one well-defined responsibility, simplifying the understanding, modification, and maintenance of the code, reducing errors and bugs, and improving its overall quality.

Names

N1: Choose descriptive names

Choosing descriptive names for functions and software elements is very important. Descriptive names are crucial for the readability and understandability of the software, and it is recommended to regularly evaluate their adequacy to avoid loss of understanding over time.

The function foo in this example does not have a name that indicates its purpose or action. Using the name foo does not help other developers understand the function’s functionality when encountered in the code. Additionally, the parameters a and b do not have descriptive names, making it difficult to understand their purposes. An improved version of this function, with descriptive names, could be:

N3: Use standard naming conventions where possible

When developing software projects, follow established conventions and standards and use meaningful names for classes, functions, and variables. This makes the code easier to understand and collaborate. Establish a common language for the project to facilitate communication and make collaboration more efficient. In short, following conventions and using meaningful names makes the code clearer and more collaborative.

N4: Unambiguous names

The choice of clear and descriptive names for functions and variables is essential in programming, as it avoids ambiguity and facilitates code understanding. While longer names may be necessary to accurately describe the function or variable, the clarity of the name is more important than its length. Better names include more details about the function or variable and clearly describe its purpose, making the software more readable and easy to maintain, contributing to the quality and effectiveness of the code.

Tests

T1: Insufficient tests

To ensure software quality, it is essential to have a comprehensive collection of tests. According to the author, many programmers rely on their intuition to evaluate the effectiveness of tests, instead of testing all possible cases. Therefore, it is crucial that the collection of tests is comprehensive enough to minimize the risk of software failures. The term “insufficient tests” indicates the absence of coverage of all possible failures.

T2: Use a coverage tool

The use of coverage tools is recommended to identify areas of the code that need additional testing. IDEs offer visual indications that facilitate the location of “if” and “catch” statements that have not been checked. In summary, the use of coverage tools is an effective way to optimize software testing.

T9: Tests should be fast

Software tests should be fast to ensure they are performed and that software quality is maintained. If tests are slow, there may be pressure to skip them during tight time periods, which can result in problems and failures in the software. Therefore, it is important to do everything possible to keep tests fast and efficient.

Algorithm

G2: Obvious behavior is not implemented

The Principle of Least Surprise is fundamental in programming, ensuring that programs are intuitive and predictable for other programmers. Functions and classes should be designed for consistent and easy-to-understand behaviors, ignoring variations in input. When expected behaviors are not implemented, confidence in the author can be lost, and it may be necessary to read the code again. Therefore, it is crucial to follow this principle to ensure that codes are clear and effective.

G23: Prefer polymorphism to if/else or switch/case

The use of conditional structures like if/else or switch/case is very common in programming, but it’s not always the best option. According to the author, most people use switch/case because it seems like an obvious and simple solution, but that doesn’t mean it’s the best choice in all cases.

Polymorphism, on the other hand, is a programming technique that allows objects of different classes to be treated uniformly, making the code more flexible and easy to maintain. By using polymorphism, it’s possible to replace conditional structures with polymorphic objects, making the code more elegant and avoiding code duplication.

Furthermore, polymorphism allows new functionalities to be added without the need to alter existing code, making the system more modular and easier to update. Therefore, it’s important to consider the use of polymorphism whenever possible, instead of relying exclusively on conditional structures.

G29: Avoid negative conditionals

When writing code, it’s important to consider the clarity and readability of the code, and that includes using affirmative conditionals instead of negative ones whenever possible. Negative conditions can be harder to understand than direct statements, which can make it difficult to maintain and understand the code in the future.

The example given by the author illustrates this clearly, where the affirmative conditional if buffer.shouldCompact()is much clearer than the negative one if !buffer.shouldNotCompact(). By using affirmative conditionals, the code becomes easier to read, understand, and modify, which can save time and effort for developers working on the project in the future.

Final considerations

As a Swift developer, I would like to share a tip left by the book’s author applied in our work environment: use SwiftLint. Additionally, I recommend enabling the text editor in Xcode and always striving to write code in a simple and clear way. These practices can help improve code quality and make it easier to read and maintain.

Thank you for reading this far!

If you would like to contribute so that I can continue producing more technical content, please feel free to buy me a coffee ☕️ through the Buy me a Coffee platform.

Your support is essential to maintain my work and contribute to the development community.

--

--

Brenno de Moura

Software engineer with a passion for technology and a focus on declarative programming, experience in challenging projects and multidisciplinary teams