Being a big proponent on crafting beautiful, robust and maintainable code, I have read several books and articles on the subject. One of my favorite resources is a book titled “Clean Code” by Robert C. Martin.
I would propose that such a resource be readily available in the company library and would even go as far as advocating for every software engineer joining the company to either have read this book or is required to read this book as part of the on-boarding process.
In summary what is clean code: Code which mostly abides by the SOLID principles of software design. In my own words.
Methods should have a single responsibility. It is better to have a class with many small methods that have a class with a small number of large methods.
Methods should not be overly long. A well known and acceptable measure is that a method should not span the entire code editor space in Visual Studio, when viewed over a 15″ laptop monitor. For example, this is a long method:
On the otherhand, this is a nice, short and terse method:
Methods should return early if possible. This avoid too many nested iffs. For example, consider the following method which takes in input object of some sort
private void InitializeActionMethods()
if (_configurationManager.Configuration == null)
Logger.Warn("Some configuration is not defined.");
We fail fast and early. In contrast, we could written the code like this:
private void InitializeActionMethods()
if (_configurationManager.Configuration =! null)
This creates a code base with too many nested-iffs which is hard to read and maintain.
Method names and variables should clearly indicate purpose. I often say code is a story. Write code as if you are writing a story. Books with shorter paragraphs are more engaging than books with longer paragraphs. I often see developers naming variables using acronyms instead of taking the time to craft out descriptive variable names. Again, if code is a story, we need to clearly identify the characters.
Entities themselves should have single responsibility. This one is also easy to violate. I have seem some very large and weird looking classes over the years. I have also seen classes that are almost impossible to refactor and unit test as it is composed of a collection of large, deeply nested methods with a large number of inter-dependencies. Keep classes small. I have told my devs that is is better to have a code base with thousands of small entities that one with a small number of large entities. The former system, if well organized, is easily to reason with, maintain, modular and robust.
Entities should have dependencies passed to them. The term coined for this is dependency injection or inversion of control. I always get confused here but the idea is for a factory to construct a car, it needs to have all of its dependent bits, such as assembly line, etc. These must be explicit and defined up front.
Unit test, unit tests and more unit tests. I cannot emphasize this enough but any component in the system should have an associated unit test which is concise. There are well documented strategies for crafting awesome unit test but they should abide by the AAA principle of Arrange, Act and Assert. Google this. Also, make these test very easy to follow. All dependencies should be arranged or created up front. if you are resolving entities from some container somewhere, which includes configuring some sort of logger, which requires some additional piece of configuration somewhere, you probably need to step back and rethink your tests and class design.
Code should be closed for modification and open for extension, as stated in the Open/Closed Principle, code should be easy to extend but closed for modification. This is a tough one but think if it this way. If you start creating code with long switches, then it is time to sit back and think of some patterns to use.
Code should be robust against anomalies but at the same time need not be overly micro-optimized. Beautiful code means that it is easy on the eye, easy on the mind, free flowing, yet robust against extremities. This includes excellent exception handling and logging.