Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News When Deferring Decisions Leads to Better Codebases: Boris Litvinsky at ReactiveConf 2019

When Deferring Decisions Leads to Better Codebases: Boris Litvinsky at ReactiveConf 2019

Leia em Português

Boris Litvinsky, tech lead at Wix, recently presented a talk at ReactiveConf 2019 in Prague describing why he thinks deferring decisions taken in the software development process can result in a better codebase. He also discussed several design and coding practices that support delaying or reversing decisions.

Litvinsky started with describing how, on a greenfield React-based project at Wix, his team struggled for over three weeks debating which state management solution (Redux or Mobx) to use for the project. The three weeks were spent doing some internal debate, followed by individual research, chained with interviews of React experts at Wix, ending in a decision matrix. The understanding was that this decision was so critical that it had to be taken there and then, and if they would pick the wrong library, reversing the decision would be impossible. It turned out that no other React-based projects in production in the company at the time were actually using any state management library.

Litvinsky reminisced that they thought that they had to choose between a right or wrong decision, while there was actually a third option: take no decision. This comes from the fact that there may not be enough knowledge at the time a problem is analyzed to actually make any kind of informed decision. Especially in the cases of decisions with high impact on the project, Litvinsky suggested that postponing a decision until enough information is gathered about the problem at hand (and the possible solutions) is the best option.

After this introduction, in the first of the four section of the talks, Litvinsky then explained in details the rationale behind decision postponement. Litvinsky thus quoted Martin Fowler’s definition of architecture:

Architecture is the decisions you wish you could get right early in a project.

Early decisions have a prominent impact, as they are much harder to revert and are the foundations for the whole application. Yet, developers tend to begin a project or product with a large series of questions, such as monolith or micro-services, which front-end UI framework to adopt, which database(s) to adopt for which service(s), Sass or LESS and more. Not all those decisions are architectural decisions which should be made early on.

Litvinsky lamented that, in absence of proper information and an holistic understanding of the context, early decisions are often biased by previous experiences with specific technologies, hype, or ego. Instead, the wisdom expressed in the YAGNI principle should lead developers to make decisions only when it is necessary to make them, enough information is available about the problem the decision is solving, and the envisaged solutions are actually effectively solving that problem.

Litvinsky justified the benefits of delaying decisions about technologies by reviewing with the audience the Hype Cycle, a concept popularized by Gartner. According to that concept, a technology evolves over time through a series of distinct phases: innovation trigger, peak of inflated expectations, trough of disillusionment, slope of enlightenment, eventually reaching the plateau of productivity. As technologies go through the cycle and mature, the use cases that they excel at addressing become clear. This means that the longer a decision related to a specific technology is delayed, the more certainty there is that the technology will be picked for the right reason.

As an example, Facebook’s CEO Mark Zuckerberg declared in 2012 that betting on HTML5 was a mistake, as opposed to native mobile application development, for a series of reasons which are easy to understand in retrospect. Last year, AirBnB explained how, after getting a better understanding of their use cases, requirements and the limitations of React Native, they decided to move off of React Native by 2019 in favor of native mobile development tools.

Another argument for delaying some decisions is that architecture is there to support requirements. Delaying to allow requirements to stabilize gives an increased confidence that the architecture is optimizing for the right thing.

For all these reasons, Litvinsky argued that no decision is sometimes the optimal decision. In the second section of the talk, Litvinsky discussed four concrete things that can be deferred.

First are estimations. Early estimations, before a proper understanding of the problem and the technical domain are often unrealistic and may be best deferred. Developers should also avoid installing any package before the need arise and is validated, and it is assessed that the need for the package does not actually arise from a design issue.

Litvinsky mentioned creating abstractions as the third activity which should not be rushed, and quoted the Rule of Three. The rule appeared in the 2004 edition of Facts and Fallacies of Software Engineering which stated:

There are two “rules of three” in [software] reuse:

  • It is three times as difficult to build reusable components as single use components, and
  • a reusable component should be tried out in three different applications before it will be sufficiently general to accept into a reuse library.

The rule of three, applied to component decomposition in component-based UI frameworks, thus recommends isolating a reusable component when there are at least three different possible uses of that component.

Similarly, the decision to break a monolithic application into microservices can often be deferred. Microservices have clear advantages, specifically when an application is experiencing scalability issues, but use of this pattern also comes with increased complexity and organizational and testing overhead. Litvinsky advised waiting for the domain and organizational boundaries to emerge before considering that option. This is in line with the advice given by Jan de Vries, Microsoft MVP on Azure, in his talk at MicroXchg Berlin in which he argued that a properly built monolith, in many cases, is superior to a microservices-based system.

The third section of the talk introduced real options as part of a thinking framework which allows its practitioners to decide when to defer a decision. Real options in the context of software engineering have been introduced by Chris Matts and Olav Maassen. Real options are the right, but not the obligation, to take some action prior to some expiration date. Real options have a price, which is the cost of the flexibility provided by the option. They also have a value, which is the benefit provided by delaying a decision. A typical example is a booking cancelling option that gives the right to the buyer to cancel its booking up to one day before arrival.

A presentation at Real Options Agile Tour Brussels presented the expected benefits of options:

A good architecture creates options for your team, your organisation and your customer. Creating and maintaining the options is continuous, daily work in small steps. Otherwise you create legacy systems that contain fewer and fewer options.

In a software development context, experimentation systems which use feature toggles allow product owners to postpone or reverse the decision of when a certain feature or code will be exposed to all users.

In the last section of the talk, Litvinsky focused on techniques for code to support deferring decisions. The first technique mentioned is Test-Driven Development, which is both a design and testing technique. TDD allows developers to delay two decisions: whether or not the functionality under test will have dependencies, and delaying the implementation of those dependencies. Spikes can be used to take an actual problem, create a naive and fast solution to explore the problem, then decide how to continue. Lastly, the modular monolith pattern may allow to delay, till it becomes necessary, the decision to move towards a microservices architecture.

As mentioned previously, deferring decisions has a value, but also a cost. Postponing too long may eliminate alternatives that may have been optimal. It may also affect negatively other teams, and making things easy to change means necessarily adding more complexity. Litvinsky thus concluded that developers should never commit early unless there is a good reason; strive to create options that will allow to defer or reverse decisions, while constantly evaluating the cost of the deferral.

ReactiveConf is a yearly conference targeted at developers with talks addressing the latest technologies and trends in software development. ReactiveConf 2019 took place from Oct. 30 - Nov. 1, 2019, and is the fifth installment of the event.

Rate this Article