Maintainable Software

Subu Iyer
Any software product is constantly changing. You have a newer version or a patch every few months. Some products are not even feature complete or stable until a few releases after the initial launch. Some run in the beta program for years! In some other cases, software is updated or rewritten to account for hardware and infrastructure changes. For example - online document collaboration services instead of standalone editors, to make use of more powerful machines and better network connectivity. In general, software tries to reach for the sky while becoming more and more user friendly. All these demand the need for software to be easily modifiable and maintainable. This essay talks about some attributes of maintainable software and the process that help to achieve the final product.

What is Maintainable Software?

Maintainable Software can be easily modified with a quick turnaround time -
To fix bugs
To refactor - make changes to the code/business logic
To make performance improvements
To make changes to account for environment and infrastructure changes

Maintainability can't be easily measured, but some qualities like modular design, good documentation, good infrastructure for development and testing, processes to track and monitor, etc. make software easier to maintain.

Why do we need Maintainable Software?

Maintenance refers to bug fixes, addition of new features and improvements to existing ones and involves modifying any existing code, data, configuration parameters, etc. It plays a big part in Software Development Lifecycle. Maintenance accounts for 70% of the time spent in the lifecycle of a software product. In case of agile and incremental development methodologies, where features are added and modified frequently and on a regular basis, most of the development effort is intertwined with maintenance work. In other words, all work involves editing existing code and other dependencies. So to ensure good quality of the final product, it is very essential that it is easy and quick to modify the existing code, build, deploy and verify that existing functionality was not broken or lost.

How do we create Maintainable Software?

Documentation

Documentation is probably the most ignored part of the Software Development Process. This is not just limited to Product Requirement, Program Specification and High Level Architecture documents, but also Test Plans, detailed bug reports, comments in code and it lasts for the entire life of the software. Specifications are not only useful during creating the software components, but they are more useful during Testing and Maintenance. These documents should define the interaction of different pieces, the external interfaces, etc. Program Specifications are also the basis for Test Plans and Test Cases, so testing effort can only be as good as the specs. In most cases, however, test cases are written based on the program behavior, which just defeats the purpose!

I also believe that not everyone should be allowed to write documents. A good writer knows how divide the program into different contexts, knows how to unambiguously describe the features and is willing to keep the documents in sync with the requirements and the application. I am not sure if there is any correlation between good documentation and success of a project, but documentation provides a good start to investigate issues many months or years after coding the application.

A very common misconception nowadays is to confuse Agile Development with Cowboy Development, hence no documents, no comments in code, no logging of bugs - basically, by-passing all processes that are meant to help development. Agile Development calls for documentation in each iteration and constant updates to documents! A document does not fully cover the project or product, but it talks about the iteration and the changes to the product in that iteration.

Component based Architecture

A lot has been said about components, object oriented design and reusable pieces in text books, but there is an abundance of software in the real world that is just poorly designed. You can clearly see that the objective was to put together a quick and dirty program and no thought was given to the work involved during maintenance.

As an example, let us look at an application that displays a questionnaire to the user and based on the answers goes to the next step to display information related to the user's answers. This questionnaire is part of a bigger application, say an online store where the user, shopping for an entertainment center, answers questions on his budget, room size, etc and the application displays a list of suitable systems.

A quick way to implement the questionnaire is to script this logic, glue it all together with a bunch of 'if...while...do' blocks and it is done, quick! Now imagine, adding more questions or removing some - careful... don't break the existing flow! This gets worse if you have to add branches or display different lists at each step. Even worse when you have to create a new questionnaire for another product, different sets of questions, different logic and so on. The only way to do this is to have two different scripts and then test and maintain different scripts. This whole thing can get ugly in no time!

Another way to do this is to implement an engine that serves out questions and each question can have a set of answers. The branching, based on the answers, in the questionnaire can be defined by specifying links from one question to another. The standard behavior of the engine can be overridden by custom handlers attached to the questions and answers. The configuration is stored in the database or in some configuration file and gets loaded by the questionnaire engine at run time to evaluate the users' response. The good thing about this approach is that we can test the functionality of the engine, not the individual questionnaire. Any future versions of the questionnaire will just work as the engine has been proven to work. Implementing new questionnaire also does not involve any code work, but just creating configuration files. This may seem to be a more difficult and challenging effort, but subsequent releases and maintenance is a lot easier.

Standard Frameworks, Application Containers

Instead of writing our application from scratch, we pick an existing (popular) application and our build our pieces to run in this container. The application handles the network, protocol and data layers, we add the business logic for our requirement. Such standard containers also come with tools to test and troubleshoot. All this cuts down development and testing time. The framework/application is already tested and proven to work. Some advantages of adhering to standards are that you are not reinventing the wheel by making use of reusable components, enhancements to the frameworks you are using also leads to enhancements to your application, having standard interfaces/protocols is good because you'll find third party vendors that make software compliant with the framework. In general it is easier to find documentation and people with skills and willing to work on a standard framework than a proprietary one.

Design Patterns and Coding Standards

It is good to have one! Having a coding standards, improves readability and understandability of code. It is difficult to make all developers think and write similar code, but if they follow standards it is much easier for any developer to work with anyone else's code. Following design patterns is more important as it gives you a known way of tackling a problem. Analyzing the task at hand and choosing the right pattern is still a major challenge, but once that is done you have a proven way to build your application. As these patterns are formulated after much iteration, they are tried and tested. By following patterns, you tend to build applications that have cleaner and organized code; the applications scale well and can be tested better and more efficiently.

Build Processes, Environment Setup, Automated Deployment

Once set up, this should be a brain dead process! There are many widely used (and free) tools to run the build and deploy the application like ANT, Maven, CruiseControl, etc. These require some configuration via scripts or XML files and will need some time and effort to get going, but once setup you are set for the life of your application. Any incremental changes will only require some editing of the existing configuration. Don't let anyone tell you that the build and deploy for your particular application is so complicated that human monitoring and intervention is required. The human here is mere interference. No matter how careful and responsible this person is, he will copy files to wrong locations every once in a while and bring the whole environment to a halt. Build and Deploy just can't be a manual process!

Automated Unit Tests, Automated Functional Tests

Automated Testing is often overlooked and in most cases considered a hassle to build and maintain. Automation Testing is not a part time task; it requires considerable knowledge of software development, automation tools and the application being tested. The objective behind automating testing is to create suites of regression tests which attempt to catch broken functionality when changes are made to the application. Only automation can ensure that a feature is tested without fail every time. With a good suite of automated regression tests, you can be sure of catching broken features during reworking/refactoring. This gives the development team some confidence when they work on fixes and enhancements. Whether automated testing is required should not even be the subject of discussion, what really needs to be decided is the automation technology, the extent of test automation - the number of tests, the functional areas to be automated, level of test and results logging and reporting features.

While there are no easy ways to measure software maintainability, following the above guidelines and best practices will get you closer to quicker and smoother maintenance cycles.

Published by Subu Iyer

1  View profile

To comment, please sign in to your Yahoo! account, or sign up for a new account.