Software development — Optimization for changeability and simplicity

Michal Szorad
4 min readMay 23, 2021
Photo by Djim Loic on Unsplash

As a person who worked on a few startups, I am aware that the requirements change way too often.

Requirements change and you should be ready for that change

One day your team needs to build a feature A, the other day we need to build a feature B before A, the other week we need to change A to C, and B to D. The other month we need to change C to Z, Z to C, and C to z.

Me building a perfect architecture and then hitting a wall

When I was younger and less experienced in software development, I always wanted to have the perfect, most efficient, and most robust code. I couldn’t stand any code snippet that occurred in two different files. NO REPETITION! NO REPETITION! NO REPETITION!— this sentence was stuck in my head.

Back then I was building my personal projects in C# and started experimenting with NodeJS. When I was working on my personal projects, I had no deadlines, all the time I wanted, and so I could experiment with building the application in a no-repetition approach with my “perfect” architecture. I was feeling really good about my architecture. But the truth is, I was probably the only one who understood the code, and after some time... There would be nobody who could understand the code.

When I started working for the first startups, I was overwhelmed by all the work and requirements that change every single week, _every single week_. I would not have enough time to use my no-repetition approach, as it was very time-consuming. I had to change the way I was thinking about code, as I was not meeting our deadlines and instead wasting my time on something I called “architecture”.

One day I was so overwhelmed that I decided to build an endpoint in the simplest way possible. It took me only a few minutes to implement the requirements, the system was working, integration tests have been passing, and most importantly, the client was happy with the results. I have decided to build the endpoint using Express in NodeJS, and I made a direct MongoDB selection from the Express route callback. When I later had to change the response data structure, I had no issues even when using TypeScript.

I have continued with this approach for the next few weeks and things went quite smoothly. I have managed to build more endpoints compared to the old architecture. I had fewer files to manage. I had better confidence in my code.

Later, when a new employee joined our company, I introduced him to our project and I was surprised that he had almost no issues understanding the code, as he was already familiar with Express and MongoDB. He was productive in the next few days. Thinking about that in my bed later the same day, I have realized that my old solution was overengineered.

Learning from the mistakes I have made

Realizing my mistake has opened my eyes and since then I am now thinking differently when programming a production-ready solution (I do sometimes experiment with different approaches on personal projects). Simple things are easy to understand, easy to change, and easy to build. I am working as a full-stack JavaScript developer and this had implications on my backend and also frontend architecture. React is my main tool when developing UI, but more coding tips on that topic will be in the next article.

For example, when building a single use-case class, library, or React component, I usually ask myself. “What would I need to do this kind of a job and to do only this job?” This encourages me to think about the dependencies before I start the implementation and prevents me from building something that may be unnecessary, or from building something that can be a dependency to my class/component/library. This leaves me with an easily testable class that is highly reusable and not so complex, as my main focus was to solve one single problem.

Conclusion

The software architecture will never be perfect and having imperfections in the code-base is absolutely normal. I haven’t seen any code-base which could not be improved in any single way. If you did, please let me know! The good thing is that we have the opportunity to think about the future use-cases and to make changes to our code-base (some tips on refactoring will be published later). The improvements can be done in readability, testing coverage, static typing, linting, documentation, … You got the point.

--

--

Michal Szorad

In ❤️ with JavaScript, React, and TypeScript. I enjoy writing clean code, contributing to open source