Software quality is the most important thing to consider when embarking on a software development project. High-quality software is important because it provides real business value and can prevent catastrophic failures and losses. Consider how almost all aspects of modern life are controlled in one way or another by software. Software is in our TVs, smartphones, air conditioning units, cars, airplanes, and so on. The world’s financial system is particularly dependent on software. For example, SWIFT (Society for Worldwide Interbank Financial Telecommunication) relies on software to process the hundreds of millions of financial transactions a year that essentially constitute the global economy.
A textbook definition of software quality contains two distinct core tenets: functional quality and structural quality. Functional quality refers to how well the software conforms to designs and technical specifications, while structural quality takes into account characteristics such as code maturity, maintenance requirements, and security.
As software leader David Chappell has written, there are three main stakeholders in any given project. These are sponsors (who pay for the software), developers (who write it) and users (who use it). These stakeholders often have different views on the relative importance of functional and structural quality. For example, users often care more about the functional quality of the application than the structural quality of the code. They tend to focus mainly on things like UI/UX and response time. On the other hand, developers tend to place more emphasis on the structural quality of the code, sometimes overlooking the functional quality of the application or certain shortcomings in UI/UX details. Finally, many sponsors concentrate on business value and delivery dates above all else, sacrificing structural quality in order to save time and money in the short term — which often impacts system maintenance and update costs in the long term.
Risk and cost management are the main motivating factors that go into creating an objective, economical, and realistic software quality model. The first term, risk management, refers to the type of problems that could be caused by a lapse in software quality. Consider what would happen if an airplane’s navigation system malfunctioned, or the life support technology in a hospital was not reliable. To avoid such failures, the FAA (Federal Aviation Administration) issues personalized software quality metrics and standards for avionic equipment, and the FDA (Food and Drug Administration) issues a proprietary set of validation principles for medical devices. The second term, cost management, refers to financial costs which can arise due to quality issues in software. For example, in 2011, AXA Rosenberg Group suffered a software glitch that caused a loss of around $217 million of client money. If this was not bad enough, securities regulators also fined the company an additional $25 million. If a larger international bank or SWIFT suffered a similar failure, the consequences could be far worse.
The main questions we ask when it comes to software quality are “What can we do?” and “How can we deliver software that meets these standards?”. Systems architect Paul Dorsey writes that developers must first establish a sound project management structure, either Scrum or another schema. Every development team requires a clear methodology to follow from the beginning of a project to the end. Support from top management is also a very important factor. This can come either from within the company developing the software, or the company paying for the software. Software development is not a straightforward, assembly-line process — there might not be a running system or functioning UI even at the midway point of a software project. Champions in upper management are therefore useful to help keep projects running smoothly.
Dorsey emphasizes another point: developers need to convince sponsors that allocating resources for planning, architecture design, refactoring, etc. adds real business value. Sponsors must understand that these steps reduce development and maintenance costs significantly. Dorsey’s third requirement for success is technical leadership. Your technical lead simply must have experience and delivered projects under his or her belt. He or she must fully understand the business logic involved, as well as every detail of the system architecture and the technologies that will be utilized. Take the example of building an equity funding platform. The lead developer or project manager needs to understand all the legal requirements of the business — financial regulations and the overall legal context — in order to ensure that the platform ultimately abides by the rules. In addition, he or she needs to understand the main motivations of users, in order to prioritize the level of importance of each piece of information involved in the software construction process.
It is estimated that an experienced software engineer injects 100 or more defects for every thousand lines of code. Only around half of these defects are caught during compilation. There are many tools to help developers detect these issues. Modern IDEs (integrated development environments) like XCode, Android Studio, and PHPStorm allow developers to avoid some of these issues in real time (during coding). However, a significant number of code or algorithm defects always survive to be injected into the code. More of these issues can be detected through unit and regression testing, which help ensure that bug fixes and new features do not replicate existing errors in other areas of the code. In addition, automated tests are continually improving the software quality and productivity of development teams.
Code review is another well-established method of ensuring software quality. Michael Fagan, the inventor of formal software inspections, has done pioneering work in formalizing code and technical specification reviews. These inspections streamline the software development and testing process, ensuring a high level of software quality. They can also be applied in the architecture design stage of a project.
When software sponsors begin to push for a deadline, the project lead is often tempted to add extra developers to the team in order to speed up the process. This presents a risk, as explained in IBM veteran Fred Brooks’ classic book “The Mythical Man-Month”. When Brooks was working on a project with a tight deadline, he instinctively added more programmers —
but instead of helping to meet the deadline, this delayed the project even more. This paradoxical effect is due to the fact that new developers need to learn the existing code before contributing to it, and because larger numbers of people on a team generate communication difficulties. Also, the more developers on a project, the greater the project management effort required to keep them all synchronised. Another important maxim to remember is Amdahl’s Law, named after the computer scientist Gene Amdahl. This law states that certain development tasks cannot be parallelized, and bottlenecks will be created if the number of developers exceeds the maximum number of tasks that can be parallelized.
The polymorphism of a system is yet another important factor in software quality. It may be tempting to create system classes and interfaces as you code, without strict pre-planning, but this often results in delays later on in the process. Software development is very similar to construction engineering and requires accurate blueprints. To return to Paul Dorsey, who stated in one of his articles: “If building engineers built buildings with the same care as software engineers build systems, the first woodpecker to come along would be the end of civilization as we know it”. Even if diligent planning appears to consume precious time at the beginning of the project, it will reduce the overall time required for final delivery, and will also confer a robustness to the code that makes it easier to understand and debug.
An additional way to achieve software quality is refactoring. All systems, especially large and complicated ones, contain poorly written code. It is important to understand that this is a normal byproduct of a complex process. Certain parts of the code will always eventually require refactoring, even if they are functioning properly. It is always possible to improve a codebase, and it is advisable to do so regularly in order to ensure that the poor quality of some modules does not compromise the performance of adjacent modules. As computer scientist Martin Fowler writes, these improvements may occasionally appear “too small to be worth doing”, but in fact, they significantly reduce defects, improve quality and performance, and bring added value to the software. It is very difficult and costly to simply maintain bad code, and even more troublesome to add new features to a poorly designed codebase. Unfortunately, refactoring is not an intuitive process for non-developers to understand, and therefore some sponsors are unwilling to invest resources into it, even though it does save money in the long run.
Code modularity is also a very important aspect of software quality. Modular code is easy to understand, maintain, and improve upon with new features. Sometimes it might be necessary to refactor some of the code to ensure modularity. Again, even though this won’t provide discretely identifiable improvements like new features or bug fixes, it raises the quality of the code and decreases overall development and maintenance costs. The modularity of the code can also be improved from the architecture design stage of the software development process. A formal inspection can help by identifying weak points in the project’s architecture.
To ensure quality, it is crucial to write complete user scenarios. Developers should attempt to get into the mindset of their end users. They should be thinking and acting like their users as they design, develop, and test their software. Designers tend to think that everything they create is clear, intuitive and easy for users to understand. That is sometimes far from the truth. It is helpful to conceive of hypothetical user cases and ask all stakeholders to participate in this process. People tend to act in closed in-group patterns of thinking and struggle to break out of them by themselves. Software engineers are no exception. Therefore, formal test scenarios, test cases, and marginal input scenarios are needed to ensure software quality.
Another advisable practice to help attain a high level of software quality is increasing the maturity of the code base. Most developers utilize copy-pasted code in their work at one point or another. When implementing something similar to a previously-developed feature, it is easier to copy-paste code than it is to refactor it into an encapsulated method for later reuse. However, copy-pasting code increases the size of the code base with no added benefit, and makes testing and bug fixing much harder. Developers often end up having to fix one bug several times as an error-filled line of code is copy-pasted and replicated throughout an entire project. Avoiding copy-pasting decreases the risk of replicating bugs, all while improving the overall functionality of the code base.
Always keep in mind the limits hardware imposes on your software. Today’s advanced hardware offers immense capacity, but even so, developers should aim for efficiency. Reducing CPU usage by even a few percentage points is not as marginal an improvement it may appear. Consider a mobile system for which battery life is a major device limitation. A simple 1% optimisation of CPU usage might add many minutes of battery life, thus significantly increasing user engagement and overall satisfaction. In addition, even with considerable technical advancements, the storage capacity of mobile devices is still not unlimited. This must be taken into consideration when developing an application. For example, small optimizations to 3D rendering engines can improve render time for complex objects from two days to eight hours, with the same hardware. Such improvements, when layered on top of each other, can significantly enhance business value and the general user experience.
Code comments are another important tool to create software quality. Any software development project has to be easy to understand by a newly-onboarded team member (or by a new team entirely, if the project is transferred to another company or corporate division). Code comments help ensure that the project is highly transferable and that new developers can quickly and easily grasp the essentials of the code. It is highly advisable to use IDE-specific code comments that automatically generate documentation — for example, XCode-specific comments, which generate documentation using Doxygen or HeaderDoc. Almost all modern IDEs support a standardized comment format that can be used to document code.
Maintenance is one of the chief factors influencing the overall cost of a software product. When beginning a software development project, the focus should be on the long term. How much will hosting cost? How much will it cost to ensure system functionality for the anticipated runtime of the product? Does the software require full-time human monitoring, or can this process be automated? These are only a few of the questions that should be asked and answered before a single line of code is written. All of these variables can be managed by planning ahead. Moving deliberately impacts the business value of a software product, because it helps to control the true cost of the project — not just the development cost, but the cost over the entire lifetime of the software.
The software development market is rapidly growing, but this growth all too often comes at the expense of quality. Project managers and developers must be prepared to justify the importance of software quality to all stakeholders, as well as explain what needs to be done to attain it. We must accomplish this with arguments accessible to non-developers, taking care to emphasize the added value software quality brings to a business. A concern for software quality should not be an optional consideration, but a routine process. After all, as Will Durant (inspired by Aristotle) once wrote: “We are what we repeatedly do. Excellence, therefore, is not an act, but a habit”.