Sunday, July 27, 2014

Source Code reflects personality of ours & our organization

As I see more & more code within my organization & outside, more I believe in Conway's Law (source: Wikipedia).

Organizations which design systems ... are constrained to produce designs which are copies of the communication structures of these organizations.


Its really amazing! This is not just limited to organizations, but also to the individual personalities. I believe, the code we write reflects our personality. We write code according to the way we think & behave. And also we behave according to how we write code!

Research paper from Nachi Nagappan called "The influence of Orgnaization Structure on Software Quality" provoked me to look at the things from different angle. I thought I would share my experience too. 

Let me start with something simple, but which has got profound impact.
Look at the following source code (source: http://googletesting.blogspot.in/2014/02/minimizing-unreproducible-bugs.html):
-----------------------------------------------------
void ScheduleEvent(int timeDurationMilliseconds) {
  if (timeDurationMilliseconds <= 0) {
    timeDurationMilliseconds = 1;
  }
  ...
}
-----------------------------------------------------
Apart from the fact that this superficially innocent-looking code has an devastating impact on predictability of software behavior, this style of coding also shows reflection of the Processes in the organization.

Many organizations turn bureaucratic as they grow. Reason why their processes become so complex, is that they try to accommodate every possible condition. There are some conditions which are aught to be handled. While some conditions are IMPOSSIBLE - with reasonable probability, there are also some conditions, which are probable, but can occur rarely. These conditions are typically "exceptions"!

A good programmer values simplicity. He/she doesn't penalize the core logic to make it complex, just for handling some condition, which is rare. If such condition occurs, he/she puts a try-catch block & specifies a separate flow to handle such scenarios.  On the contrary, programmers from a bureaucratic organization treat all conditions at the same level & handle them with if-then-else checks. This makes not only their code harder to understand & change, but also make their processes counter-productive.

Let me take an example. When I joined my organization, it was small. It had a very open culture. There was environment of trust. No swipes, no time sheets & unrestricted internet access. This made employees motivated & productive.  As the organization grew in size rapidly, we had less control on the intake of the employees. It was observed that a few employees were taking undue advantage - or rather were abusing internet resources. In order to tackle this, management imparted the following process:


  1. Certain categories of websites including social networks & even You Tube was rejected by Proxy Server.
  2. A very restrictive limit on amount of data one can download / amount of bandwidth one can consume.
  3. Its quite possible that a developer may need to download some code from open-source / download libraries or even watch some video on You Tube which is related to his/her work. In that case, he/she can send an email to IT-Helpdesk. The helpdesk either temporarily allows the site or downloads the resources on developer's behalf.


It was very frustrating as a developer to be in a flow of doing some work & just realizing that I cannot download or access something. Our IT folks are very efficient & they used to serve our requests quickly. But its not just a question of time. Writing code / Testing software / or doing any work has "its own rythem". Such things used to break our rhythem. Effectively, we made our processes very complex & made ourselves less productive - just for handling a few cases of abuse.

Purpose of processes is to make our life simple, not harder!

However, if anyone really cared to count no of abuses of internet resources, they were very very few. Instead of having if-else checks everywhere, we could have dealt with them as "exceptions". In the "catch" block, we could define a "separate code" to handle such exceptional - but possible cases!

Because of one incident of an employee doing a fraud, a company made their "reimbursement process" very complex. This penalized productivity of their employees & in-turn that of the company. Nevertheless, those who wanted to cheat, could find some other way to meet their objectives. No processes are guaranteed to be fool-proof, neither the code. Recently, that organization learnt from this & decided to deal with such incidents as "exception". Effectively, provided a try-catch block to have separate logic. Process became simpler & employees rejoiced.

One very important thing that I learnt from my gurus, helped me a lot as a developer.
That is:- Understand that following three scenarios as different & mutually exclusive:

  1. ERROR HANDLING: If one can cook up a test case, pass it your program as black-box & reach your code with erroneous inputs, then you are aught to handle it. 
  2. ASSERTIONS: These are to be used when your code assumes certain condition (e.g. pointer to be null, bade face pointer from BREP body) to be IMPOSSIBLE. That is, it is not possible for such a condition to occur from inputs to your programs. Only possibility that this condition to occur is a programming mistake in some other part of the code. (Typically, that other part of the code is written by programmers, who are humans, like you & me! And humans do make mistakes!)
  3. EXCEPTIONS: These are to be used to deal with conditions / scenarios which are possible, but rare. e.g. unavailability of server in client-server application. At times, server may go down, but we don't really want to pollute the code with if-then logic all over the place. Better we should handle it separately.
All three things above are equally useful & important. Key is to learn what to use when!


More examples to follow from my subsequent posts...