Every feature has a cost

This is something we all know, but we still somehow prefer to add all the features we can in fear that the user might be missing something. In doing so, we spread our effort across many actions and thought patterns and allow context switching to take bigger chunks of our time. When attempting too many things in parallel, the usability and usefulness of what we release start to suffer. It becomes harder to understand what we did right or wrong after the fact, even when getting feedback, because the relationships within the system became so many that it is no longer self-explanatory what effect each inter-component interaction has on the final outcome.

We may add features on top of each other, which creates problems, especially when the number of layers starts to grow. If we then decide to remove a feature in the middle, we may not have the flexibility to do so, because everything above it would fall. The more features we add on top of each other, the more inflexible the construction becomes. Each layer needs to communicate with the one on top of it, which increases the time to output within the system. A similar problem may appear in a horizontal chain as well, when the next action relies on the previous one, which has to be considered when creating long chains of actions.

The more features a system has, the more eyes and hands it needs in order to be well-maintained. A previously usable system developed by many people during an economic boom may no longer be usable when many developers are forced to quit. This indicates that going at a slow, but constant average speed and persisting longer is often preferable over using all existing resources and relying on them to be always available. The desire to work in parallel can easily lead people to believe that they should contribute with their own features, when actually a collective, single feature would be more appropriate for the system.

When working on a separate component, it may become less obvious what other people have already finished and what can be readily reused. This may lead to duplicate functionality or other synchronization costs. Documentation can be of great help (if not overdone) since it improves communication. But it is insufficient to expect that just because it is there, it will answer all questions. Good documentation is a feature in itself.

Features need to be organized in a way that makes them self-explanatory. If someone has to jump 30 lines earlier to see the value with which a non-descriptive variable was initialized, then their productivity will suffer as a result. There is no value in making things hard to understand for others, especially when working on a team.

It is easy to forget that programming is a creative act, when the number of off-the-shelf components we could integrate into our projects grows every minute. The problem of integrating then takes precedence over the problem of creating, which causes many to believe that how we combine the various utilities is what matters most, even when they recreate a different version of a past reality. This in turn may lead to the desire to study even more components rather than new ways of thinking, seeing or experiencing the problems that we are trying to solve. Finding new approaches, thinking about addressing entire problem hierarchies and combining knowledge from various fields to do so are all valuable skills, which, when we look for shortcuts, we forget to practice. These skills may remain inhibited due to our desire to reach to the next component. It is not the actual feature or component that matter, but the depth and richness of the thinking that went behind them. This is what makes them as beautiful as they are. If someone asks you “How can I do this?”, there is a benefit in taking your time to answer and think thoroughly about it instead of rushing to recommend concrete components without explaining the reasoning behind the choice. The second is much easier, which is why it is often preferred in answers. But it doesn't contribute to learning anything new.