Writing Effective Software

Following points come out of my experience (includes reading, I read a ton) of reading/writing software for 12+years (~4 years professionally). The listings are unordered in terms of importance.
This is not my laptop. This is here because the other image at bottom is not a good cover image.
This is not my laptop. This is here because the other image at bottom is not a good cover image.

1 — You cannot write good quality software at high speed without automated test cases and CI/CD

Ideally, you should be writing software at peace. Do that whenever possible but the real world is different. Competition, being first to the market, experimenting puts us next to deadlines.

Deadlines are fine, some of us cannot do it without them. What is not fine is overwork, extra hours and similar structures. As Peopleware (an excellent read, highly recommended) puts it, employees normalize the extra hours put in knowingly or unknowingly and it is not worth it (because unhappy people may leave, you trained them or paid them while they learned your system and a new guy will have that process repeated — related yada-yada).

Now we can come to the point of how do you maintain a high speed of development without breaking stuff. Enter automated test cases and CI/CD.

Unfortunately, not all code out there is testable. If I am told to take a guess, I would suggest that much more code is not testable than testable and by many folds.

The obvious segue would be: How to make my code testable?
Glad you asked, luckily there are a huge number of resources, libraries and talks out there to help you with this one, here is a list of my favorite: —

  1. Working effectively with legacy code (book)
  2. CorgiBytes — follow this company, they are amazing
  3. Refactoring (book)
  4. Martin Fowler “Workflows of Refactoring” (video)
  5. Dependency injection (wiki)

2 — Functionality is an asset, but code is a liability

If you are managing a software team or have been writing a lot of code for a few years then by now you would have realized that writing code and putting it out there is not the most expensive part of it. The expensive part is maintenance (and testing) of the code.

I love delightful experiences and tiny thing(s) i.e. any functionality albeit small may be the thing keeping a user with you than the competition and I am not saying to jeopardize functionality for less code. Neither I advocate trying to write minimum code as possible by using shady language constructs to fulfill your OCD of less LOC.

What I would say is, for the 1st cut of your software. Apply 80–20 principle aggressively if you can do it. Do not cut out the mission critical features and always think about how you will add the features/functionalities that you are dropping for now. Have a backup plan and build the system to support potential future feature requests but do not attempt to do anything and everything in one go.

The crux is getting your software in the hands of users as quickly as possible. There is nothing better than real life feedback from actual users.

And then there are few other glorious resources on this subject:

3 — Global mutable state is evil

Probably as an industry we have learned this in the hard way that global mutable state is bad. It makes your software’s state unpredictable and difficult to test.

If you are working on a huge legacy code base and are working on a feature (because business requirements) rather than refactoring the code to be more testable then do not let the broken windows theory make you spiral into writing bad code. Instead, be mindful and aware of the global mutable state. The least you can do is to make sure any new function you write takes parameters of whatever it uses and does not rely on any global variable, class or function. In my experience, just starting from here makes everyone’s life much easier.

Resources related to this point, again one of my favorites:

4 — Declarative (functional) vs Imperative

With the boom into front-end frameworks like React, Redux, Vue, and Preact we can say that it is not just hype. A boom of this scale can only come because there is a problem of the same scale.

I am not saying that you cannot achieve this with pure JS but to do that the developers need a lot of discipline as a team.

With callback hell and other complexities in JS land, the industry has been looking for a solution for some time (Looking at you Angular 1).

What frameworks like React give us is a functional way of writing UI in a declarative manner. It is much easier to reason about and test your code when it is declarative.

(I will take a moment to pay my respect to people who are working on making web better with ES6, ES7, they are finally solving the bigger issues with glory and might)

5 — Documentation

Whether you do it by comments or use an auto-generator for documentation or if you are in the code should document itself bandwagon. I do not have any prejudice here. All I hope for anyone writing any sort of professional code is that be mindful of the person who will be reading it. Try to think of your early programming days and think whether a young you would be able to understand the code you are putting out there now. In short be compassionate.

If you are unable to feel compassion then be very afraid. But document.
If you are unable to feel compassion then be very afraid. But document.

Resources :

6 — Do not push your users on a specific browser/device whenever possible and make the web more accessible

While it is alright to start with quick POC on a specific platform as your service grows bigger, you should increase your code delivery coverage on various platforms.

Also, think about making your software more accessible. Instead of investing time in solving an edge case where an animation doesn’t work properly and yada-yada. Work on making it accessible instead, it is easy to get started with and this might by your killer feature over the competition.

7 — Read more code

This is the single best advice you can give to any programmer (no matter what stage of their programming career they are in). The benefits of reading code are (not limited to):

  1. Learn from the best (open source is state-of-the-art)
  2. Learn new techniques in things that you know you can implement
  3. Once you get the hang of a framework, library or any other open source project. Contribute back to the community. One thing that I know about the open source is that open source code does not write itself.

Here is my little open source contribution showcase (boasts):

The first PR where it all started:

https://github.com/standup75/cropme/pull/34

Flask profiler love :

https://github.com/muatik/flask-profiler/pull/49

And more :

N — Conclusion

I am going for an open-ended conclusion, for now, this post is nothing short of a rant that I have written in the last hour. It needs expansion, love and I have gazillion corners to fill in my own software writing process. Reader’s discretion is advised. I can think of adding mentor, pair-programming into this along with more resources.