Baby Steps for Building Better Software

Hogea Alexandru
The Startup
Published in
11 min readApr 11, 2020
Photo by Priscilla Du Preez on Unsplash

A plethora of tutorials and guidlines are available over the internet about how to build “the perfect web app” or how to be “a better programmer”. This article is none of that. It is neither a tutorial, nor a set of guidlines, but a collection of personal thoughts and experiences regarding how to perform better as a software engineer.

Spoiler alert: It won’t teach you any sort of technology or programming, but you will, hopefully, learn something more valuable.

What motivated me to write this article?

In order to have a better grip on what I intend to tell you, you must first understand why I decided to write this article.

I have been writing software for the past 4 years and I am proud to admit that I have learned everything I am about to tell you now by making a lot of early mistakes. In my opinion, it is better to fail fast so you can learn something more meaningful from it, than trying to be the best from the very beginning.

Me and a few colleagues have been recently assigned the management of a project that started less than two years ago and its deadline is coming with blazing speed. And boy, what a project that is!

Imagine your worst nightmares materialized in some tens of thousands of lines of code. And those lines are in a desert. And you have no map. And you have no gravity. And the sand is in your eyes.

Our team’s first contact with it was disastrous. The biggest challenge was not to repair the project in the first place, but to understand everything that had been done so far. There were so many things done wrong that it became a beast of its own. It was so poorly designed that it could have been easily mistaken for one of the hell circles in Dante’s Inferno.

We managed however, through fire and brimstone, to bring it afloat, so it would be more than functional after the deadline hit. However, this unfortunate experience made me realize how many things could go wrong if left unchecked in this wilderness we call “software engineering”. So I decided to provide you some personal insights I have gathered, as I mentioned before, over the years.

Enjoy!

Life is too short for bad software — a very angry software engineer

Information is the most important asset

Whether you are building a web app, a house, surgically operating a patient, or learning how to play the piano, the information you are working with is the most important thing in the whole process. Why? Because it dictates the very flow of the process.

Imagine that you want to build a platform that handles *insert what you want to do with that platform*. If you don’t have everything sorted out, regarding the data you will use, how it will interact with the system and how the users will interact with the platform before you start to actually write the very first line of code, this little detail can turn into a disaster down the road.

Be fully aware of the purpose your software will be made for

First of all, you need to understand the whats, whys and hows:

  • What is the software supposed to do?
  • Why is it supposed to do that?
  • How will it do that?

These 3 questions are the founding pillars of every software you will ever build. By answering these early on, you will have a clear picture about the final product you wish to build. Use them to guide you through your journey!

Understand the data you will be working with

When we talk about software, data is everything. The most basic purpose of the most basic piece of software is data handling. In order to start building your platform, you must have a clear idea of the data your system will consume and produce.

Most of the time, features present in a software are centered around how the data is structured. This is actually part of a complex Software Architecture pattern called DDD (Domain Driven Design). But in plain English, this means that the way your data looks and feel will determine how the features will be developed and behave.

Design your data

Whether you will be using SQL or NoSQL, it is good to have some sort of data design implemented before you actually create your database, so it will be easier for you to spot pitfalls and optimise the data’s structure early on. There are many tools that let you accomplish this, the most common one being the might pen and paper.

When preparing to work in SQL environment, I like to design my data using dbdiagram.io. This is a very nice web app that lets you draw SQL tables.

Small example of using dbdiagram to design a tiny database for a web programming lecture

But trust me, pen and paper work amazing too! Especially when you are very early during the data design process.

Choose the technology for data wisely

OMG MongoDB is so cool! OMG ElasticSearch is great! OMG CassandraDB is the real deal! I am pretty sure you all heard at least one buzzword relating a certain database technology.

A few years ago, the “MEAN (Mongo Express Angular Node)” almost got its star on the walk of fame in LA. Do not get me wrong, I do use MongoDB when the project needs it and NodeJS is my spirit animal regarding web tech, but I did not use them because of the hype (even though this is how I first started working with them, he he).

When choosing a certain technology, you must first understand it, you must know its pros and cons, its common usage patterns and, last but not least, its alternatives. By doing so, you will be sure you made the most suitable choice regarding your needs. Sure, MongoDB is cool, but maybe your project needs some ol’ plain (not so) simple SQL.

Choosing the right or wrong technology for your data will influence the development of your project a lot.

Architecture first, everything else later

Photo by Alex wong on Unsplash

After you sorted out how the data will look, you will probably rush to your keyboard and start declaring those juicy variables, right? Wrong!

Sure, code is what your app needs in order to run, but more important that the code itself are the logical processes your brain underwent in order to write that code. And do you know how you can materialize those processes? By designing the software’s architecture.

The software’s architecture is what holds together the data, the processes and the user’s planned behaviour. Without a clear architecture on paper, writing the software will result in a chaotic mess.

Work smarter

In my opinion, writing code isn’t a purpose, but a simple means to an end. So, I ask you, which does make more sense? Writing code as you would be blinfolded and spending most of your time doing that? Or carefully planning every aspect of the functionalities you desire to implement in your platform?

By creating a clear and thorough architecture early on, you will do yourself a very, very great favor, by limiting the amount of time you will spend modifying the code you wrote when figuring out that some things just don’t match (been there, done that).

Planning is essential

A very wise man once said “Failing to plan is planning to fail”. This statement is true regarding we are talking about software engineering or any other thing that involves some sort of planning beforehand.

I often spend more time designing the software’s architecture than I spend writing the code itself. Why? Because writing code is way faster when you have already prepared a plan and detailed every functionality down to their very core.

Usually, I like to use the oldschool pen and paper. It is fast, it is easy, and it servers the purpose well. Nothing beats an A3 sheet full of diagrams and arrows and process maps. However, when things get overcomplicated, I use the C4 Modelling Tool. Their proposed model of visualizing software’s architecture is very neat and they also have a plugin for Visual Studio Code, called C4PlantUML.

Think modular

When designing your platform’s architecture, keep in mind that the platform is made out of a collection of features. It is not a single monolithic function, but more smaller functions that work together.

By building modular blocks, just as you would build a Lego toy, you allow yourself more room for changes and improvements on the long run. Modularity, however, is a two edged sword. On one hand, it gives you more flexibility, but on the other hand, you need to have discipline to design how the modules will communicate with each other.

One of the most immediate advantages of modular software is code distribution. Instead of writing thousands of lines of code in single file, you are able to distribute the logic in multiple modules. This, however, starts at this step, when designing the architecture.

Do not try to impress

We, as engineers, are a special breed of creatures. We are full of pride. And sometimes, this pride may get in our way when building our beloved software.

If you ever tried to implement some stuff just because you heard it is the latest, coolest, most impressive paradigm or piece of software that is currently available and you ended up with more stackoverflow browsing than Mariah Carey’s All I Want for Christmas broadcasts during holiday seasons, then you know what I am talking about.

When I am building software, I like to follow these 2 principles:

  • KISS (Keep it simple stupid)
  • YAGNI (You ain’t gonna need it)

Even though something can be done in a more rocket-sciency way, it does not mean it should! Paulo Coelho has a very good quote for this: “We always know which is the best road, but we follow only the road we are accustomed to”.

In my opinion, it is very good to keep a simplistic approach to software. If you are building a complex system, the complexity will come naturally. You don’t need to overcomplicate it even further.

It is true, experimentation is the means for evolution, but you should experiment when you are doing personal projects for learning purposes, not when you build software for a living.

Walk in the shoes of your (future) users

Photo by Jake Hills on Unsplash

Unfortunately, I have seen this issue several times before: the data is designed, the architecture is put in place, time to write the code. Sounds about right, isn’t it? Wrong!

Before writing the very first line of code, one must validate their assumptions made through data design and architecture by going through every process a user would go through. This means building mockups. Yes, still no writing code until this point. Envisioning those user processes and observing how they map against the proposed architecture is way more important than adapting as you go. The room for error is substantially minimised.

There are many tools that help you build mockups. One that I frequently use is Balsamiq. It is great for sketching out use cases in a more interactive way, rather than using boring diagrams. Another alternative is, of course, the mighty pen and paper. Or, more realistic mockups, like simulating the real app, how it will look and feel, through tools like AdobeXD or Zepplin.

Be disciplined when coding

Photo by Thao Le Hoang on Unsplash

Probably the climax of this article, the process of writing code itself. I will defeat your expectation to tell you that the focus on the code is minimal, if at all, even in this section of the article. I want to focus my emphasis on more important things.

Test thoroughly

As I said in the introduction of this article, I prefer to fail fast everytime. This applies to writing code as well. It is far better to have a proactive policy, rather than a reactive one. Imagine that you wrote a few thousand lines of code and suddenly something stops working. And it relates to a poorly written function a few hundred lines of code ago. Good luck Charlie :)

By having a modular approach and by prioritizing testing everytime you develop something new, chances of massive failures through the development process are drastically reduced.

Choose your technology wisely

The same piece of advice that I offered for data applies here as well. Do not choose a technology just because it is cool. Choose a technology based on these two principles:

  • What you feel the most comfortable working with
  • What is the best for the things you need to achieve (if you have more than one tool in your belt)

As I have said before, the code is the least important part of your software. The code just follows your planification. If the planning was done right, coding in a technology you are experienced with is simple.

For example, I usually code in NodeJS because I am the most comfortable with it and its features are more than enough for what I want to build. Sometimes I use .NET Core because I need certain aspects that Node does not offer me. I even did projects in Spring and Python, because the circumstances dictated so. But there is always a reason behind my choices. You should also have a clear reason for going in a direction.

Document the code

Whether working alone or in a team, documenting is a must.

On one hand, it helps you remember what you did when you revisit the code after a break. On the other hand, it helps others understand what you wrote. If something is hard to be documented, then it probably shouldn’t exist at all.

Documentation, in my opinion, is as important as testing. A clean documentation will reflect the quality of your code and also the respect you offer to your fellow teammates (if you have any).

Be clean

Treat your code as you treat everything dear to you. Do not code dirty, do not code just so you finish coding. Respect your work and the outputs of your work will be respect by others.

It may seem easy to just throw up some few hundred lines of code that “just works”. But do you know what is easier? The feeling when you are proud of what you did and of having accomplished something by being ethical. Yes, the code is a means to an end, but that means influences how the end will manifest.

Closing words

Photo by Sebastien Gabriel on Unsplash

As you may have, or may have not guessed, anything I wrote here was not present in the aforementioned project. Do you know what was present though? The code. Plenty of it.

Thank you very much for your attention. Stay healthy and build healthy software!

--

--

Hogea Alexandru
The Startup

Phd. Student, Teaching Assistant and Software Engineer. Passionate about software architecture, microservices and DevOps culture.