Most product development starts with a good design in mind. The initial architecture is clear and elegant. But then something begins to happen. What really happens is that the programs, like people, get old. However, unlike (in most cases) people there is no guarantee that software will mature as it grows old. Even worse, if we aren’t taking care of standard Software Quality Assurance (SQA), our system is not only ageing, but infact it is rotting. A Software undesirably grows old for two major reasons –
- The product owners have failed to modify the software to meet changing needs.
- The changes are made that yield poor results.
It is SQA that determines the way we can check and improve our software quality. SQA is a planned and systematic approach to evaluation of the quality and adherence to software product standards, processes, and procedures. It includes the process of assuring that standards and procedures are established and followed throughout the software acquisition life cycle.
So, who is responsible for SQA...? Well, everyone has an influence on quality - independent of his or her status and position in the project. What developers can do is focus their eyes on the excellence of defect detection, and removal as well as on design improvements wherever feasible. Now, in case of a horrendous design wherein every component seems to be dependent on every other, it could be a nightmare to even think of changing any of them. In such a case it’s all together a different war game. But in the case of a typical day-to-day scenarios, before we look closer at defect detection and analysis, we must first look for the standard symptoms of "ageing software".
You should keep an eye out for these characteristics, especially when your software is getting older.
- Architecture and design can't keep up - As software ages, it grows bigger and bigger, but architecture and design will get flushed down and one would clearly see some kind of design erosion.
- Unused or dead code - Another phenomenon that occurs in growing software is, incorporation of features that are not explicitly requested, but are mainly incorporated by enthusiastic software engineering staff members (especially agile techniques try to avoid these "eloping features"). This surely leads to unused (dead) code. This phenomenon can also be result of inadequately performed reuse.
- Poor modularization - Programs are not divided into meaningful subsystems.
- Confusing workflow - The program's dynamic work flow cannot be derived by a static code inspection.
- Hidden redundancy - Duplicated code is infact the worst enemy of quality software.
- Inaccurate scope - The scope, or visibility, of data and methods is inaccurate and more extended than necessary (e.g., "public" instead of "protected").
- Semantic issues - Class names, variables and methods of non-framework class names are semantically worthless or irrelevant to the context of what it does (for example, the most famous "int i;”, by its mere name wonder who would tell you what it does; similarly “void doProcessing()” or “class DataHandler").
- Poorly documented code and design - Documentation might even be ignored because it is considered inaccurate. It's hard to maintain and modify code that follows the maxim "If it was hard to write, it should be hard to read." Unfortunately, there are no incentives for programmers (at least not a practice that I’ve come across) to document their code or write clear and understandable programs. In fact, it's usually the opposite; developers are urged to quickly turn out code, mainly because of unrealistic schedules (thanks, to the project managers who fail to anticipate and setup the right expectation for their team deliverables); this can even happen in agile projects.
- Exponentially increasing code changes - There is more and more code to change to incorporate new features or to fix detected errors. It is difficult to find the modules and components that must be changed and to preserve the original design when doing these changes.
- Reliability decreases - As the software is maintained by the so called workarounds or hacks, more than often the complexity of keeping track of changes may result in new bugs. Even with minor changes, known and unknown dependencies among parts of the software are likely to impact and cause problems.
- Lack of scalability - There is a lack of scalability, mainly revealed as reduced performance, as poor design (or often direct implementation) cause performance bottlenecks.
- Lack of reusability - This may concern the reuse of modules from the product itself or even from other products or platforms developed by the organization.
Now, being familiar with the symptoms of rotting software, and having seen what can turn good software into a bad one, we will look at possible corrective actions which will be hosted here sometimes soon in future…