What makes good software? I always felt this question was too big for me to answer, never seeing myself as astute in the software development business as the big guns like Herb Sutter, Raymond Chen and the likes. However, this is a blog and as blogs go you can post something today and say the opposite tomorrow. Still, I couldn’t resist putting the word “current” in this post’s headline to emphasize that my opinion may change in the future.
Over the years my view of software development changed a lot. During my studies I was an “enthusiastic purist” developer – the kind that will always look for the newest paradigms and techniques, trying to follow and use them in my own code. That was the enthusiastic part. The purist part of me insisted on following the good practices I learned along the way. There are very few good practices that are true no-matter-what, the most important one being DRY – Don’t Repeat Yourself.
While working as a software developer I noticed that, no matter the company I worked for, the level of acquaintance of existing programmers with these new techniques was very low. They may have heard of some, but no one would dare use them. Most developers stick to what they already know. The effect of this being that even if you know how to write something in a “new” way, you have to educate the other developers and convince them that there is an actual benefit to using your way. This is a good thing because it works like a peer review process, but with the natural resistance to change it becomes very hard to actually use new techniques in an existing company.
Over time I learned that what makes software successful is happy users. No big surprise there, right? But the reality of things is that making software which users will like on time usually comes on the expense of the way the software is implemented. I’m not the first to say that software development is about making compromises, but if you’re an “enthusiastic purist” that realization can be a little depressing. I had to learn to compromise in order to deliver software on time. I still think this is a little unfortunate because in every piece of software there’s room for improvements – in design, in speed, in beauty – improvements that probably will never be made.
In short, I learned that
Software should:
- work well for the user, and
- be implemented in a way that allows known future developments
These are my (current) two principles of software development. I consider their weight equal, but if these two principles still contradict each other – the first one should be preferred (or the deadline should be postponed once again.) Otherwise, you will not have users left to use your future developments. The second principle contains in it as many good practices as needed, but unfortunately not more.
I would have loved to add another principle, namely “be well implemented” or “be well designed.” However, in the real world, where companies develop products until they’re most profitable (and not a second more), we don’t have the luxury of having another principle like that. Working on the first two takes most of our time.
What are the other principles, besides DRY?
Off the top of my mind: function sizes (keep them small), global variables (don’t have many), access to members (do not allow).
There are so many, but most of them do not apply for all programming styles/fields (for example, in embedded programming global variables are more common). In this sense, DRY is unique – it applies for every programming style I know.