Tags

, , ,

Clarity

You can read your code, but can your team?

Coding is simple when you are working by yourself. Working multiple projects is no problem if you are consistent in your coding style. It is easy enough to quickly scan a few lines of code written 6 months ago to get the gist and pick up bug fixes or changes without issues.

You can read your code, but can your team? And can they read each others for that matter.

It’s not about you

It’s all about playing nice.

Coding style and conventions are about working with others. It’s all about playing nice. When a code base looks like it has been written by a large team of people there will always be a problem when introducing new members, a code base should always look as though it has been written and maintained by a single entity, because really it has, it is being maintained by a team.

Code is written for human consumption and must therefore be clear, concise, and disambiguated. Take a look at one of the simplest common errors that can be alleviated by simple coding standards:

  if (thisIsTrue())
    doThis();

Nothing wrong with this code until on a friday evening an over caffeinated team member makes a very simple but urgent fix that needs to be pushed yesterday.

  if (thisIsTrue())
    doSomethingElse();
    doThis();

Now this code is not doing what is expected. Or is it? We don’t really know because the code is ambiguous. Did the fix intend to allow doThis to execute every time and only doSomethingElse was meant to run if thisIsTrue returned true? Or was the intention that both doSomethingElse and doThis should only run if thisIsTrue returns true? Without looking at the specifications we do not know. An easy way to remedy this is by stating in the coding standards that braces should always be used, even when the if statement only has a single execution statement. By doing so the original code would have been written as:

  if (thisIsTrue())
  {
    doThis();
  }

Then the fix would have been clear:

  if (thisIsTrue())
  {
    doSomethingElse();
    doThis();
  }

Time for a change

Simplicity has staying power

Coding convention is one of the most powerful mechanisms for making code readable, comments grow stale over time particularly if they are not updated as the code changes so always the clearest picture of the code is being able to read the code itself. We could easily get into much detail about standards but to keep it short and simple we will stick with variable naming.

Hungarian notation is a great way of helping to clarify code, allowing developers to understand small snippets of code very quickly. One of the biggest problems with Hungarian notation is complexity seeing a variable named a_crszkvc30LastNameCol tends to stop people in their tracks. There is a lot of information in a variable like that which also means a lot of work if the variable changes. If we were to decide that LastName is no longer 30 characters but 60, we would need to change the name to a_crszkvc60LastNameCol, an easy task with ide’s that can refactor, but still time wasted and if a task takes too much time or is difficult then no matter the benefits, the task will at some point be skipped over, usually when it needs to be completed right before lunchtime or on a friday before everyone leaves for a beer. Simplicity has staying power. For this reason when I create a new team or start to lead a team that does not have any standards in place, I introduce a simplified version of hungarian type notation.

prefix type meaning
m_ Scoping member variable
g_ Scoping global/static variable
l Scoping local variable
t Scoping parameter
s Type String
n Type Numeric
l Type Boolean / logical
fn Type Function for languages that support passing functions about
p Type Pointer for languages that support pointers
o Type Object

All variables are made up of a single Scoping and a single Type prefix and in camel case, and that’s it. Very simple.

m_lMyVariable is a boolean member variable.
lcTemporary is a locally defined string.
tnValue is a numeric parameter.

There is no need to get into the details of if the numeric variable is a float, short, int, or long, it is a number and that is what matters, the developer knowing that they are dealing with a number and not a string or an object. Changes to the type of number happen quite frequently during development, moving from a short to int when an overflow bug is hit for example, and with this simplified notation, that does not cause the variable name to change, however changing of scope or of basic type (i.e. number to string) does cause the name to change as these are changes which require a good bit of thought. Why was the country a string and now changing to a number? Why is the system user being changed to a global static variable and do those changes make sense. The types of changes that force a change in the logic should require a bit more work.

A small snippet of code now becomes fairly clear:

  @Override
  public String toString()
  {
    return m_oException.toString();
  }

I don’t have to see all of the code to know that m_oException is a member variable of this class and that it is an object.

  FUNCTION GET( tcFile, tcLocalFile)
    LOCAL lnRetVal
    lnRetVal= m_oFTP.FTPGetFileEx(tcFile, tcLocalFile)
    RETURN lnRetVal= 0

I don’t even have to know that this function was written in FoxPro, I can still make sense of all of the variables and see exactly where things have been defined simply by their names.

These snippets have been very small, small enough that even without the notation it would be quick enough to make sense of them, but what happens when one of your developers skypes or emails you asking for a hand with some code.

  tnRetVal= m_oFTP.FTPGetFileEx(tcFile, tcLocalFile)

Immediately from this I can see that we are in a class because we are referencing member variables (m_o), we are also actually in a function because we are referencing variables with a prefix of ‘t’ (tcFile and tcLocalFile), and we are setting a value on a parameter rather than a variable (tnRetVal = ) probably not actually what we want to do. So with a single line of code, simply because I know my team follows the proper naming conventions I can give a quick response without knowing all of the detail, including what language the developer was working in.

Simple, effective, efficient, and very powerful.

Advertisements