In the first half of this article
, we discussed the first levels of Code Quality Ladder: Correctness and Efficiency. In this sequel, we'll continue the journey, and focus on the next two: Readability and Extensibility.
Code Quality Level III: Readability
Okay, now that you know how to write code that's both correct and efficient, the next challenge is to make sure the code is also easy for others
to read and understand.
Modern software engineering is always
about teamwork. The code you write is not yours. It belongs to your team (or even other teams)
. Let that sink in. It is, then, in your best interest to set your teammates up for success - enable them to maintain your code. You wouldn't want to get a phone call on vacation telling you to get online and fix your code because no one else on the team can understand it, right? It happens to a lot
of engineers. A company once asked me for help trying to understand a piece of code I wrote a year ago - after I'd left that company!
Trust me, not a good experience.
A common industry practice used to get teams on the same page is called a coding style guide
, where a set of agreed-upon coding styles are shared by an entire team or organization. I highly recommend the Google coding style guide
, which is (and sometimes too strictly) followed by the entire Google company and is also now publicly accepted by many organizations. It is thorough and covers many common coding languages.
The Google coding style guide is very well written, so I won't repeat the content here. There is one thing from it I want to emphasize, and that is to always follow your team's existing convention even if it's slightly different from other commonly accepted conventions. The most important thing is for your team's code to be consistent.
Adhering to a coding style is a good start, but other practices are also needed to make the code readable. For example, comments should not simply duplicate the code as written, they should explain the thought behind the code and give context to the code. Make them useful
by being descriptive, specific.
Here, I purposely picked a very trivial example to illustrate this philosophy. Compare the following two ways of commenting:
int index = -1; // init to -1; useless comment
int index = -1; // init to invalid value; useful comment
Still feel this example is too trivial, and want a more meaty instance? Please take a look at the Google open source LevelDB header file
, which is an excellent example of good commenting, and originally written by Jeff Dean and Sanjay Ghemawat (the two Senior Fellows at Google).
So the key takeaway about readability is this: your teammates will ultimately be the judge of your code's readability
. The goal is for your colleagues to easily understand your code. You have much better things to do on vacation!
Code Quality Level IV: Extensibility
If you're writing code that's correct, efficient and readable, that puts you in the top 10% of coders at any organization. The next challenge -- extensibility -- is how you ascend to the summit.
Problems change. Code evolves. A good programmer can foresee changes that will come, take them into account, and write code that's future-compatible. This is the magic of "extensibility".
Let's use MapReduce as an example. MapReduce came out of the Google Search team where tons of engineers were going through similar tasks to analyze data. Jeff and Sanjay (the same two who wrote the expertly-commented code I linked above) saw a need to standardize the framework to make engineers' lives easier.
To be honest, there are many ways to standardize such a framework, and there are also criticisms that the concept of Map and Reduce isn't new. However, the power of MapReduce is that it standardizes to the right level to make using it easy. That means it's specific enough for use by Google Search engineers but also applicable to other use cases beyond just Google Search. As we all know it, MapReduce has been so widely adopted inside and outside of Google, and its creation became the cornerstone of the Web's Big Data era.
This is the key of extensibility: knowing what level is the right level? Answering this question is strangely more art than science. If you make your code too specific, the use case will be limited and every time the requirement changes, the code will need to be modified. If you make your code too generic, your clients need to do a lot to build on top on your code for their specific needs, and then it's too difficult to use.
It takes a lot of experience and intelligence to master extensibility. For most, the way to improve extensibility skills is to learn from our mistakes - try, fail, rinse, repeat. Even at Google, there are at least four or five frameworks that are built on top of MapReduce to make chained MapReduces easier. Even with Jeff and Sanjay around, it still took Google more than one try to get that right. :)
Correctness, efficiency, readability, and extensibility are not independent of each other. Readable code is more likely to be correct; low efficiency code is hard to extend. For each software engineer, the ultimate goal is to do well in all these areas. But at any given moment, each person is at a certain level. My suggestion is to assess your own level of expertise, consider where you spend most of your time and effort, then focus on mastery in that area before moving onto the next level. Avoid tackling a level before you are really ready. Keep this in mind - you cannot build excellent skills or tackle more challenging problems with a weak foundation.
I wish everyone a successful climb to the code quality summit.