KISS–Sometimes the best course of action

As a software developer, at times we are presented with problems that appear simple but require very complex solutions.  More often that not, a large number of those “solutions” do not require the complexities introduced.  Reading/debugging code developed by others sometimes leaves me thinking that the previous developer was trying to demonstrate how skilled they are or purposely delivered a complex solution to preserve their value to the project/team/organization.  I have always felt that if we spend just a little more time thinking about the problem, much simpler solutions without jeopardizing correctness can be created which helps reduce software maintenance costs.

Recently, I was debugging a very large and complex web application for a client.  The core of the problem centered around several asynchronous operations that were made from clients to populate a client-side viewmodel bound to user interface controls using knockoutjs.  The problem would manifest itself when some of the user interface controls would inconsistently be initialized.  Put differently, the user interface was “ready” for user interaction but some of the controls were not (i.e. dropdownlist with no values, incorrect validation errors, etc.) because the controls were bound to the viewmodel before the async calls completed.  Now there are many ways to solve this problem and some of them could be quite complex.  In this instance, I adhered to KISS, “Keep It Simple, Stupid”.  This may not be the “best” solution but it worked for my problem.

In order to correct the problem, I created a global counter (yes, I said global) that represented an instance of an async call.  Each time an async call was made that needed coordination with the user control initialization step, the counter was incremented.  When each of those async calls were completed, the counter was decremented and the user control initialization step was executed.  This step was updated to check the global variable for zero before continuing.  As a result, when the global counter reached zero, all the async calls were complete and the user interface could be made “ready”.  Also, error handling code (not shown below for clarity) is a part of each async call so that we are assured that the global counter would reach zero and not hang the user interface.

So here is what the code resembled (in this case I was dealing with javascript, but the approach can be used in other languages):

remainingDataserviceCalls = 0;

remainingDataserviceCalls++;
dataServiceCall1(function (result){        //async call

    process result;
    remainingDataServiceCalls—;
    completeInit();
}

remainingDataserviceCalls++;
dataServiceCall2(function (result){       //async call

    process result;
    remainingDataServiceCalls—;
    completeInit();
}

remainingDataserviceCalsl++;
dataServiceCall3(function (result){       //async call

    process result;
    remainingDataServiceCalls—;
    completeInit();
}

completeInit(){
    if (remainingDataServiceCalls == 0) {
    complete initialization;                            //make UI “ready”
    }
}

I am not stating that this is the “correct” or “best” (used loosely) solution but this approached solved my problem.  Maybe someone has a simpler approach.  That is the idea….

KISS (Keep is simple, stupid)! Hot smile

Choices

As software development professionals, we are faced with a myriad of choices when practicing our craft.  If we are starting a new project, decisions have to be made on what platform, architecture, programming language, libraries, controls, and other tools we will use to complete the project.  If we are inheriting a project, most if not all of these decisions have been made but there are times when we have the opportunity to try something new when adding new features and functionality.  In both scenarios, our clients and leaders should expect us to provide sound recommendations and or selections when given these choices.

I’m a true technologist at heart.  If given the opportunity without having to consider any consequences, I would use the latest and greatest technology that is available.  Let’s face it, it is fun to work on/with new technology.  While this may meet the needs of the project and provide me with the excitement of utilizing new technology, it is not always the correct choice.  Who is going to support the application when I am no longer on the project?  Has the technology choices gained any traction with other software development professionals?  Are there enough software development professionals in the organization and in the pool of available talent to continue and/or support the project.  Does the vendor/creator of the technology provide support and have an enhancement roadmap?  These are all valid questions and if not considered can leave a project in a precarious position during development and after the go live date.

One might think that they are just a developer on the project and think they have no responsibility for any of these choices.  I disagree.  Whether you are working on the overall design of a project or creating a method that resides deep within the codebase, you are responsible.  In order to develop software the right way, we all have to consider our choices.

When faced with choices of technologies, tools, and techniques, I ask the following questions:

  • Has the choice been made by the organization?  – In a lot of larger organizations, the choice of technologies, tools, and techniques are sometimes made outside of any single project.  Typically they are referred to as “standards”.  It is imperative that this question is explored because if standards are established, they may cover your potential choices and you might have nothing to consider.  One last note on this question.  We should always select the right technologies, tools, and techniques even if they are not a part of the established standards.
  • Is the potential choice a fad? – It is mind blowing how fast technologies, tools, and techniques are introduced.  When making the choice of using a specific technology, tool, or technique consider its “staying power” and adoption.  Choosing a fad will put the project in a difficult position and over time cause it to be difficult to support.
  • Are there enough skilled persons to continue/support the choice after I have moved on to another project?  – You will not work on a project forever.  When making technology, tool, and technique choices, make sure there is a solid pool of persons available in the organization or can be hired to continue when you move on.  If your choices are not fads, have been considered best practices or have solid adoption, then there should be no problem locating others to continue the project.
  • What is the vendor’s/creator’s plan for the choice? – Whether your choice of technology, tool, or technique was created by a single entity or the results of the efforts of the software development community, you must consider its development plan.  Can you receive support? How frequently is it enhanced?
  • How well does the choice integrate with any existing technologies, tools, and techniques? – It is rare to build or work on a system that does not integrate with other technologies, tools, and techniques.  Consider this before making choices.  Selecting a technology, tool, or technique that does not integrate well with the existing environment when that is a requirement is asking for trouble.

After exploring these questions, I typically have enough information to determine if the potential technology, tool, or technique is right for the current situation.  Of course these choices are made at a point in time and all technologies, tools, and techniques become obsolete but at least there is some substance behind the choice and it can be explained if someone asks.  While I think these questions are a solid starting point, there are many more questions that can be explored.

As a software development professional, how do you make choices about technology, tools, and techniques?

Z96PZS5YD9DU