Why not add this new feature?
The Web Dev Zone is brought to you in partnership with Mendix. Discover how IT departments looking for ways to keep up with demand for business apps has caused a new breed of developers to surface - the Rapid Application Developer.
How many times have you used an application and said They should just add this feature, it's so simple to do I could make it myself. This is acceptable from people that do not know the complexity of developing software, but as a programmer observing the work of other teams you should know best.
Here is a series of reasons why you don't see your wannabe feature in your favorite product yet. Essentially, try to view the same feature from the point of view of other roles in the development team and its stakeholders (all hail the buzzwords!)
Error cases: what happens when the scenario cannot be completed? Besides the happy path, what are the failure paths and how can they be dealt with? What error messages should be displayed or ways offered to the user to exit from this situation?
Testing: adding a feature does not just mean cranking out lines of code, but also making sure it works! Preferrably, with automated tests that can be run for the rest of the life of the product in a controlled environment. The reason for these testing requirements is to avoid regressions in the near and far future, since breaks will be caught by the safety net of the suite; moreover, tests serve as living documentation, either oriented to the next business users proposing a change in the specification or to the next developer having to modify code he didn't write.
Migration: when working on a code kata it's easy to start over. However, they may be external factors such as other applications, organizations or drivers that rely on the old system and that need retrocompatibility when an improvement is made. Maybe the data present in the existing system has to be migrated towards new persistence mechanism; or you have to setup a smooth transition by making use of the old and new features configurable via Branch by abstraction. This overhead is common and a requirement in production systems, to minimize the risk.
Usability: when you're talking about adding something to a user interface or the user's mental model of software, the space that can be occupied is always limited. The load of an additional screen or input is so worrying that the world's best search engine sticks to a text box and a search button (two actually).
Complexity: if every possible feature was added to a product, the complexity of its internal object and data model, and of the user interface, will go out of scale. Features seem to scale linearly: the client requests to add as many features as last month; however, the complexity they produce may be more than linear since it should also count the interactions between them, which are O(N^2). Clean designs and refactoring help in avoiding code rot, but products have mass and each line of code contributes to the increase of this mass making it harder to steer and accelerate.
Maintenance: also on the subject of product mass. One of the few things where *cravattata software engineering and Agile agree is that the Total Cost of Ownership of a feature consists in many products of its maintenance more than the initial development. It's easy to just think that you'll pay the cost once, but even the best design occasionally needs rework after the context of the system changes (such as an external API being deprecated or updated.)
Logging: especially when integrating multiple systems (internal to the company or external), the interactions will have to be logged to find the points of failure. The load placed on the use case by production system is going to be far more comprehensive of corner cases than the few happy and error paths that can be tested in isolation: a good logging mechanism can report these problems so that the code can be extended.
Security: even simple features can have a security impact, either because they expose too much information, or because they create new attack vectors. For example, every API endpoint is potentially a new way to set up a Denial of Service attack, depending on how much data it returns.
Priorities: this feature may be easy, but aren't there better choices on what to work on right now? The time of a development team are limited and they should target the goal with the best economical impact, either in the short or long term.
Economics: how this feature is going to justify its (total) costs? Serving a few users doesn't cut it, and a quorum of them has to exist. Often a feature is a bet on the presence of users that would appreciate it or be won over (as an aside, the Lean Startup movement tells to keep these bets as smaller and fast as possible).
Technical debt: on a green field project, it's easy to go fast. But on legacy code it's difficult to make even the smallest change as you first have to pay down some debt, understand how the change impacts what's working right now and cover the area with tests in order to speed up the next change to it. Adding a checkbox seems easy, unless that data is elaborated by a single procedure 10000-line long without any unit test saying what it ought to do.
(A few) conclusions
There are many reasons for a feature to be cut and there must be equally strong ones to keep it in a product. Just ignoring the weight of features on a product that shoud continue flying high can lead to code monsters, both at the functional level (complex UIs and poor cohesion), and non-functional one (technical debt sky rocketing). So the next time you want to see a button or a dialog added to some software you're using, put yourself in their team's shoes.