Path Undefined
— An undefined path of life.

Let's Talk About Clean Code

There is a very interesting phnomenon in the IT-industry. You wrote a piece of code, which you thought is deadly simple, intuitive and easy to be understood, and then you committed it, pushed it, and then you got the feedback from experienced developers saying that "it is not clean", because "you are repeating yourself, it is not DRY" or "it is the best practise to do this this and that but you are not doing it".

It seems that those "rules" and "best practises" are objective. As a junior developer, it's your duty to follow these objective rules.

In my humble opinion, this couldn't be more wrong. Each and every project, technology, environment, team, management, even the history of the project are different, how can we say there is one rule ruling them all?

I learnt programming since I was a child. I was aware of clean code not because I had read the book, neither because I had been told to do so, but rather because I found my code is not comprehensive anymore after 2 weeks of development. That's why at that time I was already aware of the basic motivation of clean code. The project should grow without taking a disadvantage of "I cannot understand it anymore" or "I cannot change it anymore" in the future, and this is still my goal nowadays behind the persuing of "clean code".

But if those "rules" and "best practises" are becoming a set of "golden rules" or "silver bullets", do they still have this motivation behind them?

I don't think so.

I have seen so many code bases, they follow a same pattern. Abstract layer over abstract layer and methods calling after methods calling. You want to change the code to fix a bug? You are welcome to modify over 20 files, and there is no garantee that you won't cause side effects, even though the test coverage is 98%. And it is exactly the time that I know, someone has persued the rule of "Don't Repeat Yourself" too much.

DRY itself has a good intention behind it, it urges people to think about abstraction of the structure. But it has been clearly overdone. There are 2 different types of repititions. One is the repitition on the surface, which means the different pieces of code looks exactly the same; and another one is the repitition of the intention, which means the different pieces of code serves the same goal (even if they don't look the same). Which part should we get rid of? For me it is clearly the second part. Because that is exactly the motivation why we want to make the abstraction. But if we are just extracting code because they "look the same", then:

  1. it is not intuitive for the reader;
  2. it is very likely, that one instance of the repitition is going to change alone, and what should we do now? We could:
    • change the abstracted part to support more different situations, then as the time goes, the abstraction will have to support thousands of different situations, which makes the code base bloated and hard to be understood;
    • change the single instance not to use the abstraction, then why we extract the code at the first place?

This is only one typical examples that I have faced in the industry, but there are more. There are too many actually, there are too many people just following the rules instead of thinking about what is the motivation behind it.

So many people are waving those words like "KISS", "DRY", "SRP", "Open-Close" like weapons to crusify the heretics, which makes me feel so tired. Not because these principles are wrong, but rather to crusify a colleague at workplace is probably the last thing that the author of those principles have ever thought about.

To me, the best lesson that I have ever had about clean code is not being taught by a developer, but by a manager. I asked him about the situation in the company, while explaining, he has used a lot of words like interface, module and all other IT related terms. It has inspired me, because that was the first time that I have realised, actually to manage the code is just like managing a company. Probably managing code is even easier, because code doesn't play office politics.

Inspired by the idea to build the relationship between company management and programming, with a decade experience of writing code. I have summarized all those priciples into 4 simple considerations, which I have to do before writing clean code:

  1. be clear, which part of the code (which department) is doing what, and how to make different modules of the code (different departments) communicate with each other efficiently;
  2. be specific, how a task has been done (company processes), describe it in an easy way to be understood;
  3. be aware, the programmer (the process designer) who wrote the code (company process) is not the only one who needs to understand the code, because the code is not only for execution but also for communication;
  4. be open, different people have different way of thinking, discuss with logic and facts for the best solution for the situation.

According to this set of considerations, would you establish a "document stamping department", just because there is a stamp on each of the documents that the company sends out? This is actually exactly the problem that I have seen behind the source code where DRY has been overly done though.

I really hope the people in the IT-industry could be more pragmatic instead of dogmatic.