What is Good Software, Really?

Joshua Hunsche Jones
4 min readAug 17, 2020

There are easily as many ways to think about software as there are software engineers. In fact, it seems safe to say there are probably N+1 ways to think of software because humans are not inherently efficient or consistent. Anyway, today I want to focus on one of the two most important lenses we can use to view our software. The first, of course, is to look at a piece of software through the eyes of the end user. The second way, which I’ll be discussing today, is from the perspective of the internal team who will need to support, consume, or build off of this particular piece of software. The balance between these two perspectives is a separate topic, but suffice it to say for this rumination that both lenses are important and we can have to use both to help us decide what constitutes “good software.”

Customers first

From a custom perspective, good software solves a specific problem, hopefully in a way that surpasses their expectations based on their experience in a particular domain. This can mean reactions ranging from, “it is rough, but it gets the job done quickly and well,” to “I had no idea I even needed something that worked like this, but now that I have used it, I am never doing it the old way again!” I love the topic of user experience, so make sure to check back for a future post that goes more into depth on this first lens of good software.

Also, don’t forget about us

To diverge from the well-worn path a bit, I would like to posit that the perspective of those who have to work with a piece of software when they Bluejeans in to work tomorrow is a close second in importance to the customer perspective. For a team member, good software solves a problem in a way that is understandable and easy to reason about. Don’t get me wrong, most technical solutions that bring value are not truly “simple” in nature, but a good software solution should feel simple at each level of abstraction. This clarity of design can be hard to achieve, and certainly can require more up-front time investment, but the payoffs are enormous.

In practice

It is entirely possible, for example, that a well-built solution will run for quite a while on its own with little to no maintenance required from the teams that built it initially. If it needs to be modified or expanded upon in the future though, an easy-to-reason-about piece of software can save a team hours, days, or even weeks of time. I’ve also noticed clean code tends to beget clean code, and an easy-to-understand codebase can help encourage future contributions to follow the same spirit of clear design when they add their own contributions.

Having worked with services that functioned like this as well as several that did not, I can say from personal experience that the difference is night and day. I love digging into a well-designed service to learn how it works and to discover how I can implement something new. On the other hand, I dread the feeling of wrangling a sketchy service to figure out why something is not working the way we expected it should. This later scenario often becomes a self-perpetuating cycle and future contributions are just glued on wherever possible since it is easier to just say, “it was already a mess when I got here.”

In the end, solutions that are hard to reason about will eventually need to be rebuilt from scratch because they will no longer be extensible or maintainable. In a way this is essentially the same as just throwing away all the engineering hours that went into building the poorly-constructed project in the first place. In contrast, a code base that was purposefully built from the beginning in a manner that enabled iteration can continue to be extended and modified long after its creators have moved on to something else. The costs and benefits of clean code shake out to a net gain on all timelines longer than the immediate.

Why I ❤️ Ruby on Rails

This two-lens approach to evaluating good software design is a large reason why I love working with full-stack web frameworks like Ruby on Rails or Phoenix. They provide an understandable layout of code and tools at different levels of abstraction, allowing me to focus on one thing at a time. With a team of Rails developers, we can deliver new features and services at an incredible pace without generating mountains of technical debt, because Rails gives us the tools to write clean, maintainable code the first time.

Conclusion

Software design can often feel like it is just a continuous stream of tradeoffs and hard choices. It is imperative though, that we who contribute to this process do not get pulled under by the current. If we take the time to look at our decisions both through the lens of the problem we are solving for the customer, and the mess (or hopefully lack thereof) that our path will leave for us to clean up later, we can help prioritize decisions that will make for happier customers and happier, more agile teams. Good software is a win-win solution for everyone!

--

--

Joshua Hunsche Jones
0 Followers

I am a determined life-long learner and creator, as passionate about well-designed technology and software products as I am about meticulously crafted music.