Think about what you’re doing when you next write a test, code a feature or fix a defect. Why are you writing that test, coding that feature or fixing that defect?
There is more to software development than writing tests, delivering features or fixing defects.
Whether our software is intended to produce revenue, reduce costs or simply entertain, it has value that persists past the end of the day. We are building a business asset, a construction of code and file, of protocol and convention, of graphic and sound that (despite its essentially non-physical nature) has value in its own right.
This surely means, if we are to call ourselves professionals, that we need to ensure our actions are consistent with building the greatest possible value into that asset, both now and in the future.
Some of the consequences of this observation are obvious.
Features that are desirable, intelligible, reliable and usable increase the value of the software. Conversely, features that appear useless, cause confusion, are defect ridden or are difficult to use all decrease the value of the software.
But some of these consequences are not quite so obvious.
Technical debt might not directly erode the value of the software, but it degrades the effectiveness of future investment. Remember that the future starts tomorrow, so today’s shortcut might easily become tomorrow’s stumbling block.
Poorly written code, whether intentionally or accidentally obfuscated, decreases the future value of the software by increasing the likelihood of defects and increasing the costs of maintenance.
Magic features, those only available to those who know the appropriate incantations, decrease the value of the software for everyone else because those features may as well not exist.
External dependencies, especially those tied to a specific product release or patch version, reduce the value of the software by artificially restricting the lifespan of the system.
So what are we to do?
We need to keep in mind that our job is not to write tests, deliver features or fixing defects but to build an asset that delivers business value for some time.
Technical Debt needs to be minimized and paid off, both by making intelligent choices about how we achieve todays goals, and by paying attention to the creep of obsolescence.
Poorly written code should never be acceptable and any instances must be remedied in a timely fashion. The SOLID principles and a robust automated test suite can help, but aren’t sufficient in their own right.
Magic Features should be documented and the user experience enhanced so that every interested user can discover and use them. Visual affordances and first-class feedback mechanisms are useful.
External Dependencies are a necessary evil that can’t be completely avoided, but only take the dependencies that are necessary and do your best to ensure your needs are as generic as possible. Avoid building dependencies that are specific to a particular environment, product version or implementation.
When programming for our own amusement, we do so for an infinite variety of reasons. When working for business, however, we write tests, deliver features and fix defects to achieve a simple goal: To create an asset that delivers ongoing business value.