Tuesday, July 16, 2013

Who do You write code for?

TL;DR: You should write code in a way that your colleagues would understand best. After all, they will be the ones that will be reading it over and over again. No matter in how much of a hurry you are, you should always take the time to give things meaningful names.



Who do you write code for? It's a simple question with an obvious answer.




As Martin Fowler bluntly :



Any fool can write code that a computer can understand. Good programmers write code that humans can understand.



The days of a programmer writing cryptic assembly code that only her computer understands have long gone by.The question deserves attention however, as I seem to keep bumping into examples that prove not everyone shares this belief (or is too lazy to act upon it).



THE EXAMPLE



Recently, I came across a bit of SQL code that looked like this:



DECLARE @nvcWFNSQL NVARCHAR(MAX) DECLARE @nvcWFNSQL1 NVARCHAR(MAX) DECLARE @nvcWFNSQL2 NVARCHAR(MAX) DECLARE @nvcWFNSQL2Bis NVARCHAR(MAX) DECLARE @nvcWFNSQL2Bis2 NVARCHAR(MAX) DECLARE @nvcWFNSQL2Bis3 NVARCHAR(MAX) DECLARE @nvcWFNSQL3 NVARCHAR(MAX) DECLARE @nvcWFNSQL4 NVARCHAR(MAX) DECLARE @nvcWFNSQL4Bis NVARCHAR(MAX) DECLARE @nvcWFNSQL4Bis2 NVARCHAR(MAX) DECLARE @nvcWFNSQL4Bis3 NVARCHAR(MAX) DECLARE @nvcWFNSQL5 NVARCHAR(MAX) DECLARE @nvcWFNSQL6 NVARCHAR(MAX) --The code goes on by initializing these variables with parts of --a SQL SELECT query SET @nvcWFNSQL = @nvcWFNSQL1 + @nvcWFNSQL2 + @nvcWFNSQL2Bis + @nvcWFNSQL2Bis2 + @nvcWFNSQL2Bis3 + @nvcWFNSQL3 + @nvcWFNSQL4 + @nvcWFNSQL4Bis + @nvcWFNSQL4Bis2 + @nvcWFNSQL4Bis3 + @nvcWFNSQL5 + @nvcWFNSQL6 --Execute the dynamically generated query EXEC spexecutesql @nvcWFNSQL



This is part of some code that generates a complex SQL query at runtime. Ignore the fact that this might not be the best idea ever, but just analyze the code itself.



THE PROBLEM



I find it perfectly agreeable, even necessary, that the developer splits up the problem into smaller problems to make it more tractable. What I don't like however is the naming of the variables. The only way to figure out what the expertly named variable @nvcWFNSQL4Bis2 means is by looking up what value gets assigned to it. This is basically the same as saying:



Screw you, maintainer of my code. I expect you to plough through 1.400 lines of code to get a basic understanding what it's supposed to do.



I can understand the developer is proud of the script she worked very hard on. That does not mean I want to read each and every line every time I have to get in there to fix a bug. That bug could very well have crept in there just because of the poorly chosen names (This is definitely the case with untested code *cringe*).



THE POSSIBLE REASONS



Why does cryptic code like this even exist? I can think of several so-called "legitimate reasons", each of which I will try to refute.



REASON 1: I NEVER THOUGHT ABOUT IT



You might get this response from a fresh-out-of-college junior. I myself did not fully grasp the importance of self-explanatory code when I started my career in software development. It took me two years of experience and a lot of reading (you can view my reading list ) to get the message. For anyone with more experience that uses this excuse, shame on you. Software development is a team sport, you SHOULD think about these things!



REASON 2: THAT'S HOW WE DO THINGS HERE



I have actually had this reason come up in a discussion with one of my clients. What if the coding guidelines of your company offer very strict rules about how you name variables? Martin from :



Coding guidelines should be lines on the ground, not concrete walls.



Whenever you are in a situation where following the guidelines would do more harm than good, just ignore them. You could take this point even further: if cryptic names result in more bugs in your code, then guidelines that enforce them are causing more problems than they're worth!



REASON 3: IT'S THE TIME PRESSURE!



We're all on tight deadlines all of the time. That's just a reality of software development. When the developer started writing the script that would become the 1.400 lines-of-code behemoth that it is now, I can somewhat understand she did not have a name for every variable she introduced on the spot. SQL is a low-level programming language that makes it harder to re-use code. There are little to no refactoring tools available in the SQL developer's toolbox, so when you write something new you just start scripting away until you've achieved what you set out to do.



I strongly believe that you should never leave cryptic code as-is, just because of "time pressure". This always blows up in someone's face. Maybe it's you a couple of days later, when the requirements have changed and you have to change the code. Or maybe it's the poor sod that took your place and now has to implement a feature in the mess you left months ago. As we all know, . As a software professional, you have the OBLIGATION to deliver qualitative software. If management does not see it this way ("Why would you spend time on code that already works?") and you cannot make them see why you need that extra day to work on it, it's time to find a new employer. That's just a recipe for disaster.



REASON 4: I CANNOT FIND A MEANINGFUL NAME



Now we're getting somewhere! You've introduced a new concept and you're putting in the effort of thinking about a name, but your mind just stays blank. Your conclusion is: "This concept is just too complex, I can't find an elegant name for it".



When you arrive at this point, we face a deeper problem. If a concept has a , it should be possible to come up with a meaningful name for it. For example, you can name the variable that holds the WHERE clause of a SQL statement "whereClause". You can name a class that is responsible of parsing HTML an "HtmlParser".



Conversely, when you find it difficult to name something, chances are that something has too many responsibilities. The solution to this problem is simple: split the concept up into parts that each have a single and well-defined responsibility and name each part after that responsibility. The resulting code will be more understandable and, as an added bonus, more reusable.



I'm not saying that finding good names for something is easy here. It may very well be one of the hardest parts of a developer's job. Literally dozens of books have been written on the topic of "naming things".



THE SOLUTION



Now, I know the developer probably wasn't trying to screw over her colleagues when she wrote the code from the example. She was just doing her job, had some working code at the end of the day, checked it in and never looked back.



I do know that if she had taken the time to reread her code FROM THE PERSPECTIVE OF ITS READERS, I.E. HER COLLEAGUES (OR HER FUTURE SELF), the names would have turned out much more meaningful. Writing stuff from the perspective of the reader is considered , but it seems that sometimes developers forget that they are not writing code for the sole purpose of being interpreted by a machine.



In the example we only talked about variable names. Of course, this principle applies for EVERY concept you dream up, be it a module, a class, a method, avariable or even the condition of an if-statement.



CONCLUSION



Next time when you are about to check in your code, take a moment to reread it from the perspective of someone that has never seen it. Is the code self-explanatory? Does it tell a coherent story that does not require criss-crossing through the code? Make an effort to make your code as clear as possible. You will save your colleagues and your future self a lot of time and frustration.



FURTHER READING



* Much of this discussion traces back to what Robert Martin wrote in hisbook. If you managed to make it this far in this post you should definitely check it out.

* A rather sarcastic on how to "Ensure your job for life", with nice examples of poor naming choices.

* Jacob Emerick's: "WRITE YOUR CODE AS IF YOU WERE TELLING A SIMPLE STORY TO FUTURE DEVELOPERS."
Full Post

No comments:

Post a Comment