I see a problem time and time again with programmers wasting an incredible amount of time writing “good code” when in reality sometimes that “good code” isn’t good at all. I fall prey to this as well, so I’m going to write up this post to put into words the code design decisions that I make subconsciously when trying to write “good code”. That way I can analyze it, and refine it in the future. This post is focused on the code itself, not whether or not the software product is of any use. At the end of the day the hardest thing to do is to create something that people want to use. That is a totally different topic.
What can I say? After 15 years of programming professionally, I’m a pretty confident coder. I work hard at it, and still find ways to improve everyday.
As Bradley Nowell so eloquently stated in “Love is What I got”….
“I can play the guitar like a mother f-in riot.” – Sublime
Well this is how I feel about code!
“I can rock the compiler like a mother f-in riot.” – Jon Kragh
There was a phase of my career where I read every patterns book, every code design book and every textbook that I could in order to become the best programmer I could be. Some examples are:
- Design Patterns
- Patterns of Enterprise Application Architecture
- Agile Software Development, Principles, Patterns, and Practices
- Code Complete
- Writing Secure Code
- Service-Oriented Architecture: A Field Guide to Integrating XML and Web Services
- The Art of Objects: Object-Oriented Design and Architecture
- Object-Oriented Thought Process
- etc…
Looking back on all of those years, I realize that reading all of those textbooks provided a great foundation on what is technically considered good code to many people. I really think people consider these practices good mainly because they were written in textbooks, and we have a tendency to trust the written word. Don’t get me wrong, there is technical merit in a lot of it too! But I’ve seen a dangerous tendency sometimes to take these texts as the “one true way”.
At the end of the day, nobody is going to care about what patterns we used if the code doesn’t work and even worse isn’t used by anybody.
Now this doesn’t mean that we shouldn’t strive for good code. I use a different way of evaluating code when I write it myself. Below is what I consider my code hierarchy of needs.
Jon Kragh’s Code Hierarchy of Needs
Does The Code Work?
The bottom layer is the foundation. Does the code work? Without getting into whether or not the program is actually useful, the most important thing is: Does the code work?
Is the code easy to understand?
The next most important thing to me is: Is the code easy to understand? This is where all of those patterns can really get in the way. A lot of patterns can be overused in situations where they just are not needed. However patterns used to help make things easier to understand are a very good thing.
Is the code consistent?
Next up is consistency. Consistency helps making code easier to understand, but isn’t the only way to make code easy to understand. It is such an important facet that it really deserves its own layer in this pyramid.
Error Handling
I’m really surprised that error handling doesn’t get more attention. To me error handling is one of the most important facets of good code. I have a pattern that I use in all of my applications for robust error handling. I have a standard way to report back validation and system errors, throughout the layers of my architectures. I cannot express how important having a good and consistent error handling strategy in an architecture is.
Conciseness – Is the code as concise as it can be?
I love elegant code. I love seeing something accomplished in one line of code that could be done in more lines of code. This is where all of those patterns an object-oriented techniques come in very useful. The most important thing here though is: conciseness should never detriment the layers below it. Conciseness can sometimes make code harder to understand and in those cases it makes sense to make code less concise in order to make it more understandable.
Conclusion
I plan on refining this post as time goes on. This at least gives me a baseline on what I consider “good code” today. I must admit, “good code” is a hard thing to put into words But this definitely summarizes my mix between pragmatism and pure code hygiene as I code today.
