You might be wondering what is there in it to discuss about configurations or extensions. Everyone seems to understand these two terms well but yet fail to set the expectations correctly with Client about what an application can do and what it cannot. It is not uncommon for developers to hear something like,
"I thought this is supported in the application without making code changes."
There is subtle difference between these two. Making a feature configurable or/and extensible will have impact on the delivery deadline. So, we will go through two main topics:
- Difference between Configurations and Extensions
- Configuration Hell
Throughout this blog, the word User refers to either an end user or a developer depending on whether you are thinking of an application feature or a library as example in your mind.
Customisations
Depending on the feature we need to add to an application, certain behaviour or style would be expected to be customisable so that users can change the default look and feel of the application themselves. Configurations and Extensions make features customisable. Configurations let user modify the behaviour of a feature whereas Extensions let user add a new behaviour. For example, if an application provides support to change the theme, then it is considered as Configurable. If an application provides support to create and plugin new notification mechanism to it, then it is considered as Extensible. Note that having an extension point does not promise that the feature is already available. It says that if an extension has been added by the user, it will be used by the application in the specified process flow.
Below given are some of the differences between these two options.
| Configuration | Extension |
| Requires no additional skill to do the change | Requires platform knowledge or coding skills |
| Easy to perform the change | Moderate or Difficult to do |
| Testing is difficult due to the different combination of feature states | Extension testing is not the responsibility of the product team |
| Development is not easy | Adding Extension Point is relatively easy. |
Though, I have tried to show the differences between configurations and extensions, it is important not to think of them as binary options. Properly designed features should support both. For example, consider a notification system providing email notifications. User should be able to configure some parts of the email like subject, disclaimer, etc. At the same time, this system should provide support for developing additional notification channels like text messages which again should be configurable. Design patterns like Factory, Observer, etc. can be used to make the extension development easier and cleaner.
While designing a feature, team must clearly define what is configurable and what is extensible. This should become one of the release artefacts so that users clearly understand how to customise features. Since it is for users, it is best to capture these as acceptance criteria in the user story. This will also help team to estimate the user story correctly.
Configuration Hell
There are some common mistakes we make when designing a behaviour as configurable. Though we say a system is configurable, we often face with situations wherein the effort required to configure a system is too much due to these mistakes. I would like to refer to these common mistakes as Configuration Hell. Let’s see some of these.
Mandatory configuration
The idea of having a configuration is to change the default behaviour if a user does not like the default one. Therefore, it makes no sense to have configurations targeting the End User (or, sometimes even developer) with no default value and declare them as mandatory. There are exceptions when a developer is the user of configuration. For example, any environmental configurations like SMTP address, connection string, etc. cannot have a meaningful default value.
Chain of configurations
When adding configuration options to complex features, we tend to end up with monstrous configuration file/settings. Assuming that all of these have been provided with a default value as mentioned before and that the intended user is developer, we can say that it is difficult to maintain this kind of configuration. Therefore, it is important not to explicitly declare all the configuration options so that the user is not overwhelmed with all the options. But at the same time, the configuration details must be properly captured in wiki for reference or for best, create a configuration tool which could provide intelligent autocomplete when user types in a configuration option and sufficient hints regarding the option.
Everything is configurable
Ask a product owner if something needs to be configurable and the response would be a guaranteed “yes“. When a component of the feature is connected to some other components or features in the application, changing the configuration could have effect to the connected components. We often simply ignore this fact and care not to test the system with different configuration values but just with the default value. Even if testing covers all the use cases, we cannot ignore the fact that adding configurations increases the lines of code and therefore, the delivery time will be more compared to non configurable solution.
Solution is, of course, not to avoid configurations. We can have two approaches to do this.
- First is to be selective and make only necessary components as configurable. A team working based on an effective agile feedback loop will not find it difficult to improve the features and hence add new configuration options based on necessity.
- Another option is to promote a configuration, especially the ones that are less likely to change, as developer only in the first stage. This way team can deliver the feature earlier with reduced testing. At the same time, when configuration needs to be changed, team can test it before providing the updated configuration to client. But this does not give a nice user experience even if there is no development required.
Validation
All user inputs must be validated by the system before it starts processing. Therefore, we add validation logic in User Interface, APIs and before saving to data store. Shouldn’t we treat configurations as also user inputs and do the validation before updating to data store? Yes, we should. Validation must cover basic checks like if the value,
- Falls within the accepted range of values.
- It is best to limit the accepted values. For example, a textbox could be configured to accept only certain number of characters. Being a number type config, it is important not to let user configure any number. This could impact the application layout if user configures a big number.
- Quality Testing scope must include testing the application with different configuration values.
- Has the correct data format.
- This is significant with the date/time kind of settings. If user enters the value in an unsupported format then system must give hint about the accepted format(s).
- Change could cause data loss or quality issues.
- Let’s say a user can add or remove fields to be displayed on the UI. When user removes a field, system must warn user if there is already data captured in that field as part of old transactions.
Classification
Configurations can be feature specific or used in multiple features. It is, therefore, necessary to
- Classify configurations based on feature where it is used. Changing a feature specific configuration will not have effect elsewhere in the application. If a configuration is used in multiple features, then it must be defined so.
- Configuration tool must display if a configuration is feature specific or not. This way a user can easily look for configurations and update them.
Summary
Configurations and extensions help make applications customisable and thus provide a better user experience by making changes to the application that is already released. However, creating customisable features make backward compatibility and testing relatively difficult. Therefore, decisions must be taken carefully when writing user stories so that tendency to make everything configurable is avoided or when required, it is done with adequate testing.