Wednesday, April 2, 2014

Software Maintenance and Message IDs

I am going to describe a couple of very bad programming practices for handling messages.  These bad practices increase the cost of maintenance and lead to processing errors.  See my article on the cost of software maintenance.

Here is the background:  It is common for one software program to send messages through sockets to another program.  It is common for the messages to have a message ID and message data.  It is common for the receiving program to receive multiple messages and process the data differently for each message.  It is common to test with a series of "if" statements.  We will use this example:

if message.id == "MyVerySpecialMessage":
    myVerySpecialMessageFuntion(message.data)

The first mistake in handling messages is to test on a substring of the full message ID string.  In Python it would look like this:

if message.id.find("VerySpecial") >= 0:
    myVerySpecialMessageFuntion(message.data)

This will work, but there are two problems.  One is that a new message could be added later that has the message.id of "TomsVerySpecialMessage".  Testing on the substring "VerySpecial" would catch this message as well and feed the data to the wrong function.  The other problem is that when searching to find where in all the lines of code the message ID "MyVerySpecialMessage" is processed, you will not find this line of code because it does not use the full ID that you are using for searching.  Searching code with functions like grep are the only way we can work with undocumented code.  Using substrings of a message ID is an insufferable aggravation for software maintenance:  don't do it.

The second mistake in handling messages is to use an else statement to implicitly handle and process a message.  An else-if statement should always be used to explicitly process a message.  The else statement should only be used to report unexpected and not-handled messages.

Here is a simple example.  There are two message IDs:  "MessgeOne" and "MessageTwo".  The poor practice of processing with an else-statement looks like this:

if message.id == "MessgeOne":
    messgeOneFuntion(message.data)
else:
    messgeTwoFuntion(message.data)

If a message with an ID of  "MessgeThree" hits this code block, it will go into the wrong function.

The proper way to handle the "MessgeOne" and "MessageTwo" example is as follows (elif is the Python way of saying "else if":

if message.id == "MessgeOne":
    messgeOneFuntion(message.data)
elif message.id == "MessgeTwo":
    messgeTwoFuntion(message.data)
else:
    reportError( message.id)

Avoid bad programming practices.  They are not outgrown.  I have seen programmers with decades of experience making exactly these mistakes.  Begin with good programming practices and stay with them.

Robert