Clean Code Literature Notes
Published: 2023-05-01 21:52:43

Clean code is the foundation of any successful software project. This is the key to creating maintainable, readable, and efficient code that developers can easily understand, modify, and extend. This article examines the importance of clean code and provides practical tips and best practices. Whether you're a novice or an experienced developer, these guidelines will help you expand your coding skills and produce quality code that meets the needs of all stakeholders.

## Knowledge Collection

In this section, there is a list of resources around clean code that are highly recommended to read, but for getting started into the topic, each will have a short summary.

### Clean Code by Robert C. Martin

Clean Code by Robert C. Martin is a comprehensive guide to writing maintainable, readable, and efficient code. This book offers practical advice and examples on how to write code that is easy to understand, easy to change, and easy to extend. It covers topics such as naming, formatting, functions, classes, testing, refactoring, and provides a set of guidelines and best practices for each. This book emphasizes the importance of writing clean code not only for personal productivity, but also for team and project success.

Some key takeaways from the book:

- Code should be easy to read and understand. This means using descriptive names for variables, functions, and classes, and keeping functions short and focused.
- Comments should be used sparingly and only when necessary. The code itself should be self-documenting.
- Code should be organized in a way that makes sense and is easy to navigate. This includes using consistent formatting, grouping related code together, and avoiding duplication.
- Testing is an essential part of writing clean code. Code should be designed in a way that makes it testable, and tests should be written to ensure that the code works as intended.
- Refactoring is a key tool for improving code quality. As code evolves, it can become cluttered and difficult to understand. Refactoring involves making small, incremental changes to improve the code's design and maintainability.

In the first section, the book covers:

- **Meaningful Names** — Names should be descriptive and unambiguous, and should convey the purpose and function of the code they represent.
- **Functions** — Functions should be small, do one thing, and do it well. They should have clear inputs and outputs and should not have side effects.
- **Comments** — Comments should be used sparingly and only to explain things that are not immediately obvious from the code itself.
- **Formatting** — Code should be formatted in a consistent and readable way, with clear indentation, spacing, and line breaks.
- **Objects and Data Structures** — Objects should hide their implementation details and expose their interfaces, while data structures should expose their implementation details and hide their interfaces.


  > [!tip] This seams heavily focused on object oriented programming.
  > Those ideas still apply when using functional programming although some might also be covered by design.

- **Error Handling** — Error handling should be centralized and should use exceptions instead of error codes. Error messages should be informative and should provide enough information to diagnose and fix the problem.
- **Boundaries** — Code that interacts with external systems should be separated from the core application logic, and should be tested using mocks and stubs.
- **Unit Tests** — Unit tests should be written for all code, and should test individual units of functionality isolated from each other.
- **Concurrency** — Concurrency should be managed carefully, and code should be designed to be thread-safe and avoid race conditions.

### Other Books

#### Refactoring: Improving the Design of Existing Code by Martin Fowler and Kent Beck

In the first section, Fowler and Beck introduce refactoring concepts and provide guidance on when and how to refactor your code. It also describes the benefits of refactoring, such as improved maintainability, flexibility, and performance.

The second section of the book contains a catalog of refactorings categorized by problem type, including duplicates, long methods, and data chunks. Each refactoring is explained in detail with examples of how to apply it to real code. The third and final section of the book provides guidance on how to apply refactoring in practice, including using automated tools, managing refactoring at scale, and integrating refactoring into your agile development process.

Refactoring provides a comprehensive guide to improving the design and quality of existing code through refactoring, and is considered essential reading for software developers seeking to improve the quality and maintainability of their code.

#### Clean Architecture by Robert C. Martin

This book explores how to design modular, maintainable, and scalable software systems. It provides a framework for thinking about software architecture and how to apply clean code principles to larger systems.

The book is divided into six main chapters, each covering a different aspect of Clean Architecture.

- **What is Design and Architecture?** — This chapter provides an overview of software architecture and design and discusses the importance of creating a clean, modular and maintainable architecture.
- **A Tale of Two Values** — This chapter introduces the concepts of “business rules” and “use cases” and explains how they should be separated and organized within the architecture.
- **The Single Responsibility Principle** — This chapter introduces the Single Responsibility Principle (SRP). SRP should only have one reason to change each module or component.
- **Open-Closed Principle** — This chapter introduces the Open-Closed Principle (OCP). OCP requires software entities (classes, modules, functions, etc.) to be open for extension but closed for modification.
- **The Dependency Inversion Principle** — This chapter introduces the Dependency Inversion (DIP) principle. This states that high-level modules should not depend on low-level modules, and both should depend on abstractions.
- **Layer** — This chapter presents a layered architecture that separates the business logic from the infrastructure and user interface layers and discusses the benefits of this approach.

Throughout the book, Martin provides real-world examples and practical advice for designing architecture for clean, flexible, and maintainable software. He also emphasizes the importance of making the architecture independent of external frameworks and technologies to maximize its flexibility and longevity. Overall, The Clean Architecture is a valuable resource for software developers and architects who want to create clean, modular, maintainable software architectures that stand the test of time. 

### Blog Posts

#### [The Art of Readable Code by Dustin Boswell and Trevor Foucher](https://www.oreilly.com/library/view/the-art-of/9781449318482/ch01.html)

This article describes best practices for writing code that is easy to read and understand. Provides practical tips and examples on how to improve the clarity and readability of your code.

It starts by defining clean code as code that is easy to read, understand, and change. Clean code is important because it reduces maintenance costs, makes it easier to add new features, and improves developer productivity.

The article also includes some useful tips for writing clean code.

- **Use meaningful names** — Use clear and meaningful names for variables, functions, and classes.
- **Write short functions** — keep functions short and focus on doing one thing well.
- **Write clean code comments** — Use comments to explain why the code does what it does, not what it does.
- **Keep Code Formatting Consistent** — Use consistent formatting to make your code easier to read and understand.
- **Minimize the number of global variables** — Be careful with global variables, as they can make your code difficult to understand and maintain.
- **Avoid nested code blocks** — Avoid deep nesting of code blocks. This can make your code harder to understand and maintain. The article concludes by emphasizing the importance of readability in writing clean code. Developers are encouraged to put themselves in the shoes of someone reading their code for the first time and write code that is easy to understand and maintain.

#### [Code Smells and Refactoring by Martin Fowler](https://martinfowler.com/articles/refactoring-external-service.html)

This article describes common code smells that indicate potential code quality issues. It provides guidance on how to identify and address these code smells through refactoring.

It begins by explaining that as software systems become more complex, it's becoming more common to use external services to perform specific tasks. However, integrating external services into your code base can be difficult as it introduces new dependencies and can add complexity to your system.

The article also provides practical advice for refactoring your code to use external services.

- **Isolate external services** — Separate service-specific code from the rest of the system by creating a dedicated class or module to handle interactions with external services.
- **Use interfaces to abstract services** — Define an interface for an external service to provide an abstraction layer that makes it easier to switch to another service in the future.
- **Use Dependency Injection** — Inject an external service into the class that needs to use it, decoupling the service from the rest of the system.
- **Create tests for external services** — Create automated tests for external services to ensure they are working as expected and catch regressions when changes are made.
- **Consider fallback behavior** — Define fallback behavior in case the external service is unavailable so that the system continues to work even if the service goes down.

This article concludes by emphasizing the importance of careful design and testing when integrating external services into your code base. This allows developers to think carefully about the system's architecture and thoroughly test their code to ensure reliability and maintainability.

#### [The SOLID Principles by Robert C. Martin](https://blog.cleancoder.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html)

This post explains the principles of SOLID. The SOLID principles are a set of guidelines for designing modular, maintainable, and scalable software. We will discuss each principle in detail and provide examples of how it can be applied in practice.

This article begins by defining SRP as the idea that there is only one reason for a class to change. Uncle Bob argues that this principle is essential to writing maintainable code.

He gives several examples of how violating the SRP can make code more complex, harder to test, less flexible, and so on. He also says that although SRP can be difficult to implement, it's worth the effort as it results in more robust and maintainable code.

This article concludes with an overview of some key strategies for SRP compliance. This involves identifying class responsibilities and splitting them into smaller, coherent classes. Uncle Bob emphasizes that these strategies require careful thought and planning, but ultimately lead to more maintainable and flexible code.

#### [Clean Code: What Is It and Why Should You Care? by Artur Klosek](https://cloudogu.com/en/blog/clean-code_en)

This article starts by defining clean code as code that is easy to read, understand, and change. Clean code is important because it improves software quality, reduces maintenance costs, and increases developer productivity.

This article discusses key principles of clean code, including:

- **Naming conventions** — Use clear and meaningful names for variables, functions, and classes.
- **Code Formatting** — Use consistent and readable formatting to make your code easier to read and understand.
- **Comments** — Use comments sparingly and only when necessary to explain complex logic or document API functions.
- **Testability** — Cleanly separate concerns and minimize dependencies to create code that is easy to test.

It covers some common code smells and signs of poorly written code. For example, duplicate code, long functions or classes, complex conditional logic, etc. It includes some tips on how to identify and fix these code smells to improve code quality. 

## Summary

After reading these books and articles, there are some key points and steps to take away for writing clean code:

- Use descriptive and meaningful names for variables, methods, and classes.
- Keep methods short and focused with a single responsibility.
- Write [code that is easy to read, understand](https://www.manning.com/books/the-programmers-brain), and change.
- Use the DRY (Don't Repeat Yourself) principle to avoid code duplication.
- Use appropriate comments and documentation where necessary to explain the intent of your code.
- Write automated tests to ensure that your code works as expected and is stable over time.
- Follow established programming conventions and standards defined by your team and the community surrounding the language and libraries you are using.
- Use [good design patterns and principles](https://refactoring.guru/design-patterns/catalog) such as SOLID to control the structure and organization of your code.
- Regularly [refactor your code](https://refactoring.guru/refactoring/catalog) to improve its design and maintainability.
- Continuously learn and improve by seeking feedback and incorporating new knowledge and best practices.

Creating clean code requires attention to detail, discipline, and a commitment to continuous improvement. By following these principles and practices, developers can create code that is easy to understand, modify, and maintain, improving software development outcomes. 

### Why Writing Clean Code is Important

1. **Readability** The code is easy to read and understand, making it easier for other developers to maintain and modify the codebase.

2. **Maintainability** The code is easier to modify and update, reducing the time and effort required for ongoing development.

3. **Robustness** The code is less prone to errors and bugs, leading to a more reliable and stable software product.

4. **Reusability** The code can be more easily reused in other parts of a project or in other projects altogether, reducing development time and effort.

5. **Scalability** The code is more adaptable and flexible, making it easier to scale a software product to meet changing requirements.

### Negative Effects if Clean Code is Ignored

Poor quality code can lead to the accumulation of technical debt, as future development and maintenance require additional work to fix or change the code.

Technical debt is a metaphorical concept that refers to the costs that arise from making trade-offs during software development, such as choosing to take shortcuts or using less-than-optimal design patterns. These trade-offs can lead to increased costs in the future, as developers must spend more time and effort maintaining and modifying the code to address the technical debt that has accumulated.

Poor quality code that does not adhere to clean code principles can lead to technical debt, as the code base becomes more difficult to maintain and change. For example, code that is hard to read, understand, and change leads to increased development time and effort, and leads to the accumulation of technical debt. Similarly, poorly structured and organized code can make your codebase more complex, harder to maintain, and increase technical debt over time.

Technical debt can also accumulate when a developer takes shortcuts to meet deadlines, deliver features faster, or omits testing or QA steps. While these short-term trade-offs may seem beneficial today, they most likely will lead to increased cost and complexity eventually.

Ignoring clean code principles can lead to more technical debt because maintaining and modifying the code base becomes more difficult and time-consuming. This can increase development costs, slow time to market, and reduce product quality and reliability. 

- **Reduced productivity** — Poor quality code can slow down development and maintenance, as developers struggle to understand and modify the codebase.

- **Increased risk of bugs and errors** — Poor quality code can increase the likelihood of bugs and errors, leading to reduced software quality and reliability.

- **Reduced agility** — Poor quality code can make it more difficult to pivot or adapt to changing requirements or market conditions, reducing the agility of a software product.

Writing clean code is essential for creating maintainable, robust, and scalable software products. Ignoring these principles can lead to technical debt, with all the mentioned disadvantages, among other negative outcomes.

## Followup

How to write clean code? What practices should be followed to ensure clean code.

### The Practical Programmer: From Journeyman to Master by Andrew Hunt and David Thomas

This book emphasizes the importance of a pragmatic approach to software development, focusing on the practical aspects of producing quality code and delivering value to customers. The author offers many practical tips and tricks for becoming a more effective programmer, including:

- Use a version control system
- Write clear and concise code
- Practice continuous learning and improvement.

The book is divided into four main sections, covering various topics related to software development.

- **Pragmatic Philosophy** — This section introduces core principles of pragmatic programming, such as:
	- The importance of early and continuous testing
	- Avoiding code duplication
	- Streamlining development through automation.
- **Practical Approaches** — This section describes some practical techniques for improving the quality and effectiveness of your code. These include using patterns and frameworks, creating flexible and extensible designs, and optimizing code for performance.

- **Basic Tools** — This section covers basic tools and practices that every programmer should know (Version control systems, editors, IDEs, and testing frameworks).

- **Practical Paranoia** — This section discusses the importance of anticipating and preventing software development problems such as:
	- Security Vulnerabilities
	- Scalability Issues
	- Unexpected Failures.

This book offers a wealth of practical tips and tricks to help developers elevate their programming skills and write better code. Many of the principles and practices outlined in this book, such as continuous learning, automated testing, and refactoring, go hand-in-hand with the concept of clean code to help developers make code more readable, maintainable, and efficient. In this sense, The Pragmatic Programmer can be considered a useful companion to Clean Code by Robert C. Martin, providing developers with a set of effective techniques and tools to help them write clean, working code. 

### Checklist to Ensure Code Quality in Your Pull Requests

- Does the code adhere to the project's coding standards and guidelines?
- Are your variable and function names clear and meaningful?
- Are there any comments explaining the purpose of the code?
- Is the code clear and readable?
- Did you comment out or remove dead code?
- Have you thoroughly tested your code?  

### Tools to Automate Clean Code

- **Static code analysis tools** — These tools analyze code without executing it and can detect issues such as unused code, unhandled exceptions, and security vulnerabilities. Examples include SonarQube, [eslint](https://github.com/eslint/eslint), and [checkstyle](https://github.com/checkstyle/checkstyle).
- **Code quality metrics tools** — These tools measure code quality based on various factors such as complexity, duplication, and maintainability. Examples include CodeClimate and Codacy.
- **Automated test tools** — These tools help ensure that your code meets functional requirements and is reliable. Examples include [junit](https://github.com/junit-team/junit5), [jest](https://github.com/jestjs/jest), and [cypress](https://github.com/cypress-io/cypress).
- **Code formatting tools** — These tools can automatically format your code to comply with coding standards and guidelines. Examples include [prettier](https://github.com/prettier/prettier) and [ktlint](https://github.com/pinterest/ktlint).

These tools help ensure clean code, but they should be used with manual reviews, not as a replacement for code reviews. Additionally, it is important to properly configure the tool and interpret the results accordingly to avoid false positives and false negatives.