I believe a lot in Agile and Lean Principles. Agile movement historically often focused too much on teams and really left Software Design and Architecture behind it. Regular Engineers often belive a lot in Clean code and take it as a dogmatic bible and only source of truth. Clean code has some good stuff like the Boy Scout Rules(Alway left the code better than you found it). However lots of clean code “truths” are not so “true” at the end of the day. I’ve found considering the code without a Design and Architecture, extremely dangerous. Most of the time I saw the worst codebases ever was related to very poor Software Design and very poor Architecture. Having a Good Architecture and Good Design does not mean you will have Good code, however, if the Architecture and the design write the code is very simple and easy to change. However, if the Architecture and the Design are wrong it might be impossible or very hard to change the code.
See the Forrest not only Trees
The right Architecture provides us ISOLATION, which means not only contain the blast radius in case of failure but also give the ability to use to DELAY some change to do it later. The Good delay property happens because we reduce the impact on customers via SOA / Microservices principles like isolating the database from the external world, having explicit versioning for contracts, having backward compatibility, having a bounded context and making the service working independently(Operations: Deploys, Databases, Runtime) from other services. Having the wrong architecture will mean sharing a database with multiple services, therefore having direct table access to between multiple services. Doing so ill hurt the ISOLATION property, therefore changes will be hard to make since you will break other people and in practice will be much harder to change. In other words, having the right architecture enables Isolations, Changeability, Debugability, Observability, Re-use, Speed Time to Market, Composability and many other interesting properties. Architecture means architecture. It does not mean Backend architecture only, it also applies for frontend(mobile/web). If we think about Micro frontends and Components they provide the same benefits as I described early.
Another way to see it is, Architecture and Design are the Forrest, Code is the trees. We need to be able to see the Forrest first the trees later. If we see the code first bad things will happen. I’m not saying good code is not important but I’m saying for sure is LESS important than Architecture and Software Design.
What Really Matters?
When you are doing a code review, what really matters? IMHO:
1. Are we doing the right architecture?
2. Are doing the right design?
After these 2 questions, let’s talk about what matters in the code, IMHO:
1. Is the code SAFE? (Are we doing bad practices like unsafe memory mgmt).
2. Is the Performance right? Are we doing the best performance? Do we have a slow code?
3. Does out code will scale? Do we have the right data structures in place?
4. It’s our code testable? via Unit, Integration, Contracts, E2E, Stress/Chaos Testing?
5. It’s this code flexible? Can we change later if we need it?
6. Is this code reliable? It will always work as expected?
7. Is this code OBSERVABLE(Observability) can we understand what happens from outside?
Often these questions are not addressed in a Code Review. Now I will talk about what happens most in code reviews, most part of the times.
Clean code is about Style
Let me tell you something. Once I was a Clean Code Zealot. Not anymore! I’m +2 years clean from Clean Code, thank God for A Philosophy of Software Design Book!
Most of the time, clean code means Style. It means having names, a number of lines and a number of methods. Often these 3 factors are not really important. They are subjective and change from people to people. People tend to spend massive amounts of time denying code reviews and going back and forth based on style and spending ZERO time on the matters that really matter like Architecture and Design(Look the 9 concerns I said above).
Style does not matter. It’s a waste of time discuss style. Really bad things happen when we focus on “clean code” and does not focus on architecture and design. What are these bad things that happen (…and they happen all the time):
1. Waste (money, time, energy) in concerns that do not matter.
2. Miss guidance — instead of focus on important design matters like(should make move this code to another component/service? are we with the right test coverage in place? Should this code be specific or generic? Should we create a library or should we keep as it is?) We end up focusing in the number of lines and number of methods. IT sucks giving names. i.g: NoSQL, NoEstimates, BigData, etc… Why do we spend so much time in something is so relative and subjective?
3. Less VALUE delivered — using this time we could be able to deliver more value to the customer.
4. Worst Understanding: Clean code does not make the code easier to understand. The right architecture and the right design does. Having small methods like there is no tomorrow and separating things that cannot work/live together does not make any advance and the opposite it creates more complexity and more obscurity, therefore, more cognitive load to understand things.
5. Worst Design: Right design requires thinking and TRADE-OFF analysis, often engineers do not value the cons only the pros. This creates a very unbalance and narrow-minded view of the solutions. In order to have better DESIGNs: Architecture, Design, and Code we need to analyze trade-offs.
6. Flaky Tests: Since we dont get the design right we end up testing things at the wrong level and have tests that are flaky and break often. Flaky tests can also be created by other reasons like bad test practices like hardcoded IDS or not doing proper data setup and tear down. However, having the wrong design will often lead to wrong test initiatives.
All these issues are created for the lack of the *Design Thinking*(PS: I’m not talking about UX). Often Engineers get the wrong definitions of a Unit. Not everything should be ATOMIC. Clean code does not encourage this discussion because often focuses on one very specific and not a precise thing: Style. Style happens because of poor languages. If you compare several languages like C, C++, Java, DotNET, PHP, NodeJS, Python, Ruby, Groovy you may realize this language are pretty similar and have only syntactical sugar differences but the mindsets are the same.
Strong languages like Haskell, Clojure, and Rust do not have this problem (they have others) but they have less space for style since the compiler has a more strong and opinionated role and the languages have less blank roles that can lead to poor decisions.
Why do we need a Clean Code DETOX?
It’s s clear to me we need a Clean Code DETOX. In 2013 Rich Hickey gave this killer presentation. Where he provided several insights but he said languages, framework and libs are like musical instruments and he lay down two facts:
A) They are made for PROFESSIONALS, not for beginners. Musicians spend very little time as a beginner. Interestingly enough I see developers spend YEARS as beginners even they are called Architects but they do not STUDY therefore do not really improve.
B) It’s okay to have effort. In software, we see effort as a Bad Thing. We see effort as waste. So it comes to the “Developer Evangelists or Developer Experience” guys saying developer life should be painless. I think like Rich Hickey, if professional musicians can do efforts, why developer cannot? Do we threaten developers like adults?
Clean code it’s not the solution. Clean doe will only give you the FALSE idea of a solution. We need to learn how to Challenge our assumptions in order to truly learn and improve. I think clean code time is over and we need to think more about Design.
In case you are wondering what is Design (Look Rickey Hickey video) he talks about it. Design is about the Structure it’s about how it works. Design cannot be generated. The design must be planned and executed. Good Design is about the obvious structure and fights against obscurity which leads to complexity. So the design should be simple. Having more methods, fewer lines of code, changing names not necessarily make the code obvious and the design simple.
Originally published at http://diego-pacheco.blogspot.com on January 15, 2020.