Nowadays, there is a very hot trend about code regarding to writing it clean. Many software gurus have written many articles, even books about this subject in the last decade; Robert C. Martin, Kent Back, Martin Fowler are a few of them to mention. As the topic of this article is stating clearly, where is the limit for writing a clean code? In order to answer this question, we have to first define the criteria for writing a clean code. Let’s start.
What Does Duplication Create?
As a developer, if you are using the same expression in multiple places in your code base, then this means you are duplicating the code. The change in the duplicated expression requires changes in all the places the expression used. Duplication not only clutters the code but also increases its complexity. As a remedy, removing the duplications or refactoring them will remove the dependencies, but it is not enough. Apart from the first-party dependencies within the same code base, there might be third-party dependencies on external assemblies or dependencies on the frameworks you are using. You have to manage them as well. As a rule of thumb, the best-managed dependency is the one that does not exist for clean code.
Keeping Functions and Methods Small
In UX design, there is a generally accepted saying that “Less is More”. The same is true for coding as well. Functions and methods should be kept small. By keeping them smaller, you make them more adaptive pieces of functionality that promote reuse. Each function should tell a single story, have a character and be transparently obvious. Only by this way of coding, you can create trustworthy functions that can be reused again and again.
The Open and Closed Principle for Clean Code
Although there are different definitions of “the open/closed principle” in the software world, we would like to progress with the below definition and elaborate it: “Open for extension.” This means that the behavior of the module can be extended.
“Closed for modification.” Extending the behavior of a module does not result in changes to the source or binary code of the module.
This definition is in line what we said in the previous criteria. Functions should be small enough to have a solid character reflecting itself in consistent behavior but also be suitable for extending its behavior. This leads to functions being adaptive to the changing needs of the customer/developer while keeping its core stable.
The Single Responsibility Principle For Clean Code
By definition, single responsibility principle encourages writing code that has one and only one reason to change. If a class has more than one reason to change, it has more than one responsibility. Such kind of classes should be broken down into smaller classes. Otherwise, the bigger class will be difficult to maintain or even may act as a trojan horse and may be vulnerable to attacks. Delegation and abstraction are the ways to downsize the scope of this kind of classes.
Unit and Acceptance Tests
Clean code should have both unit and acceptance tests. Although writing unit and acceptance tests seems a tedious work, it pays its return on investment in the very short term. With the help of the unit tests and acceptance tests, code is kept in track and extensions will be done fearlessly. Otherwise, the lack of unit and acceptance tests will prevent developer from making extensions and even refactoring the current code base preventing continuous improvements.
Although there are many debates about the percentage of unit and acceptance tests to be included in the code base, the generally accepted testing pyramid provides us a good measure to start with. In the testing pyramid, it is stated that the percentage of automated unit tests/acceptance tests should be higher than that of automated integration tests, and the percentage of automated integration tests should be higher than that of automated GUI tests.
Testability vs. Automazibility
There are two generally confused concepts; one is testability and the other is automatability. Testability is not automatability. While testability relates to human interaction and testing, automatability relates to tool interaction. Without well-written, structured and clean code, the testability of the code is very low. So, we can definitely say that testability is directly proportional with clean code. If it is so, the other way around is also true which means if your code is testable, then it is a clean code. Check your code’s testability in order to determine its cleanness.
In this article, we listed some of the most common used criteria for writing clean code. You may wonder whether they are enough to define the concept of clean code. No, definitely not. You may come up many more criteria and different levels of coverage and satisfaction levels for each of them. But whether you define a few criteria or hundreds of criteria for writing a clean code, your main criteria should be your audience, the people who will read the code after you write it at least for the next years. Don’t forget that you are writing the code for the people, not just the computer or yourself. So, understand your audience and write according to their needs. One’s clean code may be other’s dirtiest code. The answer to the question “Clean Code, Cleaner Code, Cleanest Code: Where’s the limit?” really depends.
Although our answer to article’s topic question is “it depends”, there is one reality, this reality is that well-defined, structured DevOps processes and infrastructure will definitely increase your chance of having clean code.