Suppose you want to develop a new feature, but you are not sure that users will like it, and you need to have a way to hide it painlessly. Or suppose you are working on a new big feature and want to avoid monster commits. Or just want to make the behavior of the site easily configurable. How can I solve all these problems, read under the cat.
Problem
Imagine that the development cycles of your team last for two weeks, and the implementation of a new feature will require 3 months of development from the team. At first glance, there are two possible schemes of action:
- Create a separate branch and do all the work in it for three months, periodically doing pull from the parent branch
- Use the concept of continuous integration ( Continious Integration or CI for short ): decompose the task and freeze the code in small portions
Both of these approaches have their obvious advantages and disadvantages:
Using feature switchers to solve problems
This problem is quite common in development and there is an elegant solution that allows you to take the best from the approaches described above -
feature toggle or
feature switcher .
Essentially, a feature switcher is a boolean flag that is stored in the database and contains information about whether a feature should be enabled or not. The value of this flag can be retrieved from the database by key. The convenience of using feature switchers is that they can be easily changed by a business user during runtime through the admin panel without having to re-deploy the application.
The following is an example of using feature toggle in Java:
if (configurationManager.getParameter("is.some.functionality.enabled")) {
In the example above,
configurationManager is a class that allows you to retrieve the value of a specific feature switcher from the database by its key.
Also, with the help of feature switchers, you can display / hide certain elements on the frontend. To do this, put the flag value in Model and pass it to View as shown below:
@ModelAttribute("isSomeFunctionalityEnabled") public void isSomeFunctionalityEnabled() { return configurationManager.getParameter("is.some.functionality.enabled"); }
Then use the passed value to render this or that HTML code:
<c:choose> <c:when test="${isSomeFunctionalityEnabled}"> <!-- Render some stuff --> </c:when> <c:otherwise> <!-- Render some other stuff --> </c:otherwise> </c:choose>
Types of Feature Switchers
The described concept of using feature switchers is just one possible use case and such feature switchers are called release toggles. In total there are 3 different types of feature switchers:
- release toggles - allow you to hide incompletely implemented features during their development
- experiment toggles - switches for A / B testing
- permissioning toggles - feature on / off switches for various user groups
Thus, using feature switchers, you can build two different versions of the site on the same code base, using different databases and different sets of feature switchers. For example, on a European site it makes sense to include all features related to GDPR, but on a Russian one you can not do this.
Problems using feature toggles
Since I work on a project where feature toggles are actively used, in addition to the obvious advantages of using them, I began to notice problems associated with them:
- Testing complexity : when a new release is released, QA engineers test all the features that are included in it, and also try to turn them on and off using feature switchers. This requires a lot of additional time, since it is advisable to test all kinds of combinations of flags
- The appearance of dead code : the values ββof many feature toggles do not change for long periods of time or do not change at all, and thus the code written for a different flag value actually becomes βdeadβ
- Unexpected site breakdowns : many of the outdated feature switchers have the unfortunate property of breaking something when changing their value (since no one has long verified that they work). Since feature switchers are stored in the database and can be easily changed by business users from the admin panel, breakdowns often occur due to a change in their value. The performance of long-unused feature switchers should first be checked on a test environment
Solutions to some of the problems described.
The following actions can help solve the above problems:
- Documentation of available feature switchers: in order to understand what effect a particular feature toggle has and by what key to look for it in the database, you should create detailed documentation with a description of all feature switchers.
- Periodic revision of feature switchers: to avoid the appearance of dead code, periodically remove obsolete feature switchers and associated code
Summary
Feature switcher is a very simple and at the same time powerful mechanism that allows you to avoid monstrous commits, easily change application behaviors, or assemble several different applications on the same code base using different feature toggle configurations.
However, it is also worth remembering that this development pattern has some drawbacks that result in hard-to-read and hard-to-maintain code, therefore, excessive use of this pattern should be avoided and periodically document feature switchers and their revisions to remove unused ones and, as a result, clear the project from the "dead" code.
useful links