Building software is often a huge investment – and so it’s no surprise that quality is not something to take lightly! Traditional “Quality Control” focuses on catching bugs, and preventing defects, to manage the user’s experience of the software. This is one aspect of software quality, and an important one; if a user’s experience is poor or software is perceived to be defective, many users in today’s marketplace will simply take their business elsewhere. Poor quality can harm not only software, but also reputation and even the livelihood of a business.
The type of quality most people are more familiar with can be labelled External Quality. These are the things that someone looking at the product from the outside would use to judge its quality, typically things like:
- Bugs or defects that users experience
- Aesthetics and design
- Whether the product has the right features
- How easy it is for the user to achieve their goals
- Performance of the application
External quality is crucial for a piece of software to win over users; if you get these things wrong people will most likely try to avoid your product and look for an alternative. We’ve all experienced software that we perceive to have low external quality, and it can be very frustrating. If you’re writing software for the public, or for users who have a choice, expect the consequence of poor external quality to be that users go elsewhere.
One of the easiest ways to manage external quality is to tackle “feature gluttony” and to build software that solves one problem in a focused way. It’s better to solve a single problem elegantly than to try to do too many things and do them badly. In many cases, it is the product owner who can influence this most directly, by showing restraint and focus in the features that they prioritize for delivery. By directing the delivery team’s attention to a smaller surface area, it’s easier to deliver the features well. You of course need enough features to solve a user’s problem, but there can be diminishing returns – or even a negative impact – from having too many features in a product. If you have a small, high quality, set of features, that can be enough to win the affection of users. Users may then ask for further features, and this is great because you can make a decision of whether to expand the product based on real world guidance rather than an un-tested up-front vision. Prioritize, deliver one thing at a time, and deliver it to a high standard.
If external quality has slipped for whatever reason, it may be a good idea to throttle back on expanding the application’s features, and to spend some effort on improving the features that are already there. If a feature is causing problems and isn’t “popular” or essential, don’t be afraid to simply remove it; this can often improve the overall health of a product. Get good defect detection strategies in place, prioritize resolving known issues, and things can be improved – although the results are rarely immediate and it will probably take effort.
If the external quality problem is from “building the wrong product” – i.e. building a product that doesn’t meet a user’s needs, or is too hard to use – the path can be harder. The easiest way to try and prevent this is by getting (real!) feedback as early, often, and cheaply as possible. Often a simple sketch of what a screen would look like is “good enough” to put in front of a potential customer and get feedback, before committing further resources. There are great tools out there for this, but also pen and paper can go a long way. If you’ve deferred this feedback, and find yourself in this position after launching, then the only answer may be to take a step backwards to find the right path, and rebuild these parts of the application in a way that aligns better with users’ requirements.
External quality is what will sell your product, and retain customers, so it has fairly obvious importance that is relatively easy to justify to stakeholders. It’s relatively easy to assess external quality, by getting user feedback ratings and monitoring usage.
By contrast, Internal Quality is all the stuff that the people who work on building and maintaining the software see, that the outside world doesn’t. These things can be more subtle, but have a massive impact in the long term health of a product! Internal Quality covers things like:
- The architecture of the software
- How well modules are defined
- Test coverage
- Coding style and consistency
- Choice of dependencies, frameworks and libraries that are used
It can be more tricky to see the impact of these things at first; it’s fairly well established that software engineers can have a perfectionist trait, can seem to value craftsmanship “for the sake of it” (perhaps for pride, rather than for a business driven motivation), and can see “bad code” as anything written by anything else (as joked about here) – and so “developer grumbling” can be easy to dismiss! However, if there are problems with internal quality, they can cripple a product over time, and be much more difficult and expensive to address.
The number one visible symptom of poor internal quality is that as the codebase grows, progress becomes slower and slower. Adding new features becomes more expensive, regressions become more common, developers start to fear working on areas of the system, and budgets and estimates get overrun by sometimes shocking amounts. This can reduce trust in the delivery team’s ability to deliver, and be the basis of toxic environments.
The number one root cause of problems with internal quality is poor architecture and design. Quite simply, the design that was chosen does not scale well. Martin Fowler calls this the “Design Stamina Hypothesis“. A poor design will become harder and harder to expand; but the best designs can allow a team to accelerate in ways they didn’t think were possible. Adapting the architecture of a codebase in-flight is challenging work, and normally will take significant effort. Ironically, a characteristic of a good architecture is that is easier to work with and adapt later; but teams who are struggling in this position by definition don’t have this experience. Crucially, to succeed there needs to be a change in the thinking behind the desired architecture. It may well help to bring in a consultant or different personnel; with fresh eyes and an external perspective these problems can be easier to solve, and if you find a consultant who is familiar with the problem then they might have a toolbox of other solutions available to them.
The worst thing a team in this situation can do is to simply try to overcome the slowdown by adding people to the project. If your design doesn’t scale, then adding to the problem faster will just mean there is more to fix eventually. Scaling teams is a delicate thing, and the way to achieve scale with a team is to have a design and processes that work with a small team, before adding people. Expanding a team that are in chaos will just cause the same problems but faster! The “first rule of holes” applies here – if you’re in one, stop digging! Take a step back, and think of things that can be done differently to change the trajectory of the project. Things like effective retrospectives can really help here, by inviting the whole team to contribute ideas. Think of ways to take pressure off the team, perhaps by prioritizing things that can give a quick result, to buy space to make the bigger changes. It is essential to be honest about what is going on here; it is bad news for a stakeholder to hear that a project is in this state, but by trying to hide the problems, things only get worse when the truth comes out – normally at the end of a budgeting period, when the costs/benefits of working ineffectively become apparent!
Do something about it!
Poor external quality will devalue your product in the eyes of users; poor internal quality will push up the costs of getting anything done. Both will cause long term damage, either because you have to constantly fix bugs to raise external quality, or because you’re struggling every step of the way with internal quality (they often combine and compound…). The good news though is that these things don’t happen overnight, and so by paying attention to quality on an ongoing basis it’s possible to stay in control of quality and be happily productive and build great things. According to some studies, over 90% of software teams are trying to use some form of agile practices, which generally encourage short iterations and incremental improvement. Make it part of every iteration to have an honest(!) conversation about quality, so that problems don’t have time to build up. A classic mistake is to not do this “because there isn’t time”… why not have a retrospective, so the team can talk about why there isn’t time, and address the cause!
Don’t expect to be able to wave a magic wand and fix everything overnight; if you tackle problems early it may be possible to get quick results, but if problems have been allowed to grow expect solving them to be a real challenge. By constantly looking for opportunities to make even the smallest positive impact it can help motivate the team to keep going, and make a disproportionate difference to the trajectory of the project. For the bigger things, take a step back and look at the problem with an un-sentimental perspective. Remember that everyone did their best with the knowledge they had at the time, and be respectful of the efforts that got the project to where it is, but don’t hesitate to change things if it’s needed.