Software Development & Management - II

Software Development & Management - II

In Part-I, the basic concept was explained. In this part, I'll explain it further with an example which actually led me to think in this direction.

In the beginning of my career, I worked on an IVR (Interactive Voice Response) product. The application was configurable in some ways but still most of the time it required code changes & suffered from code duplication. Even though the functionality in code existed it was not possible to use to through configurations alone. The higher management wanted a product that was available to the clients in the GUI form so that a client could configure IVR on its own. At that time, I came up with this idea to develop configurable components & prepared a proof-of-concept / demo in this regard.

The demo consisted of "tasks". One task was related to I/O i.e. play a sound file and if configured then wait for input. Another task was related to communicating with the back-end which provided the actual business logic like PIN verification. For the demo purpose, configuration related tables were created in the DB where the above tasks were configured for a certain IVR call flow like prompting a user for a PIN (I/O task) and then verifying it (PIN verification task). We can see that I/O task gets the PIN from the user and passed it on to the PIN verification task. Tasks have to have a standard interface to be able to communicate otherwise it won't be easy to wire them together for a certain flow even if they themselves are configurable.

The task interface in its simplest form is as follows:

public interface Task
{
void process(Map<String, Object> dataMap);
}

The "process" method is invoked to execute a task and is passed a map. The keys in the map are like variable name whereas the values are the actual objects. The map contains the objects for the current execution flow, may contain input values for the task & when a task returns may contain output values of the task. In case of above example, the I/O task doesn't need any input values but it puts an output value in the form of PIN & also is configured to provide the next task name which in this case is the PIN verification task. The PIN verification task then takes that output as its input to verify the PIN and puts the next task name in the map. In this case a verification success or failure can be played by the I/O task.

I/O task A
Config: play PIN input message
Input: None
Output: PIN

PIN Verification task B
Config: set tasks in case of success & failure
Input: PIN
Output: next task C if sucessful otherwise D

I/O task C
Config: play success message
Input: None
Output: your pin has been verified

I/O task D
Config: play failure message
Input: None
Output: your pin couldn't be verified

As clear from above, in this way we can configure multiple instances of same tasks to achieve different execution flows without any code changes. Currently I have implemented an IVR application based on this concept. It contains mainly 2 tasks, one for user input by playing some message and other for PIN verification using web service. By configuring multiple instances of these task different PIN related flows have been achieved like verify, change or reset PIN.

To view or add a comment, sign in

More articles by Ahmed K.

  • Factory Method

    A practical look into factory method, a creational design pattern. In this, an interface defines what type of an object…

  • Interface proxy implementation in Java

    The following article explains the need & the thought process behind the implementation of the library named…

  • Software Development & Management - I

    I have been developing software in Java for more than 5 years. So far, I have dealt with quite a bit of applications &…

    2 Comments

Explore content categories