I have been involved with the MoTech project for quite some time. I will be rolling off and moving to other projects in a bit, hence I thought this will be good time to reflect on the things that I have learnt in the project.
The post is a technical one, but this being a reflective post, I wish to do it full justice by adding a pinch of philosophy. Since MoTech was my very first project right out of college, It kinda feels like parting a friend whom you grew up with. But I guess, as with all partings, you never leave someone completely, for as Vivekananda points out, character is the sum total of one’s experiences. Similarly my time on MoTech has shaped me in ways, I would not have thought possible a couple of years back. With that, I wish to take a deep dive into my technical learnings on the project.
Programming to predicates
I consider this to be one of my greatest learnings on the project. I have blogged about in greater detail over here. In essence, handling one off cases in systems is a very bad idea which could lead to a lot of complexity down the line. If you are solving a problem, it is better to solve it the correct way, though it is very tempting to do the easiest thing possible.
Back at college, I was introduced to the book Object Oriented Analysis and Design by Grady Booch. Though back then, most of the content was way over my head, I realised something. The way you build a software, ie the process is almost as important as the product. When the product is of sufficient complexity ( like many non trivial pieces of software ), the only chance that we have of mastering this complexity is by following a sound process.
This book got me excited about decomposing the system into objects and there by reducing the complexity of the software significantly. Back at college, I tried to apply OOAD to every piece of software that I built, but somehow, I ended up creating systems that are complex to understand.
Then at Thoughtworks, I got introduced to the excellent book titled Domain Driven Design by Eric Evans. In that book, Evans describes certain stereotypes of classes that should be identified in any software system. Evans argues that some of these classes should be named with names taken directly from the domain of the problem, and encapsulate knowledge directly from the domain. These classes called domain classes should be separated from classes like Controllers which encapsulate an application level concern like intercepting a HTTP request.
In essence, Domain Driven Design involves creating a Domain specific language that will be used to describe the system by all the stake holders. The amount of expressiveness that this system of thought brings to software is immense which could be appreciated by listening to this excellent talk by Guy Steele on the design of the Java programming language.
Devops is a system of thought which emphasises the importance of breaking down silos of knowledge which lead to poor software. Devops emphasises that any piece of code written by a developer should be directly deployable to a live system.
This requires a developer to think from the perspective of multiple people like QAs, traditional support people, traditional documenters etc. In essence, developers must be poly-skilled and such poly-skilled people effectively reduce the turn-around time from creating a specification to deploying the system.
Specifically, I have found that a sound knowledge of the UNIX operating system is invaluable not only from the perspective of devops, but systems engineering in general. Devops in short, requires a developer to think from all the perspectives outlined in Kruchten’s 4+1 view model.
Unit testable code
Any concern in the system should be unit testable. If the verification of a concern needs tests on two or more units, then a new unit (aggregate) should be identified and the test, and consequently, the functionality should be moved to the new unit. Unit testing at this level adds orders of more magnitude than fitting tests to poorly identified units. This is consistent with the fundamental argument of Dijkstra in his seminal paper, that we should try to keep the symbol space of a program as close as possible to the runtime space.
Finding the root cause of a problem in a complex system could be a difficult process. Once it happened that our application suddenly stopped calling customers. We assumed it to be some problem with the code. But figuring out what exactly was the problem by reading thousands of lines of code is a stupid idea.
When debugging a problem, one has to look for very specific data and reduce to the scope of the problem. This requires a fundamental change in the way we write a piece of code. The code should be written in such a way that it becomes trivial to figure out that the problem does not occur in that piece of code.This can be achieved thorough logging, audits etc. Oh, eventually it so happened that the calls were not made because a firewall was silently dropping connections to the application.
When debugging, isolating a problem is important. Data and logs are crucial to help us isolate. But what do you do when it so happens that you dont find the answer by digging through data? In such cases, It helps to test out the feature in an older version of the application, make sure it works and then narrow down the search for the problem to only the differences between the two versions. Martin Fowler has written an excellent blog post on the topic over here
With everything said and done, great software will be created by great people who trust that the person next to them will put their heart and soul into the project. Once you find someone giving everything they can for the sake of the project, ability does not matter anymore. It is fantastic to work in such an environment and I have seen quantitative differences in terms of the number of bugs, time lines etc when software is being developed by a team with lots of trust as opposed to software which is developed by a team where one person thinks that they know best.
Quote for the day,
“The frog at the bottom of the well drifts off into the great ocean. Heh heh… yep… pretty damn honourable… pretty damn honourable” – Jiraiya