While working on a project involving two applications an issue came up involving site customization. It illustrates the importance of not fighting the nature of a given thing when faced with a design decision involving that thing. This heuristic will usually save you a world of headache even if you can’t immediately think of circumstances in which it’ll prevent error.
There are 2 products (aka applications); when product A is installed, product B is also installed. Unlike product A application B is often installed by itself.
Application B has a wonderful piece of software for site customization. So wonderful in fact that it’s being drafted to perform its wonders in service of application A.
While going back and forth about the best way to accomplish this, someone suggested having the site customizer automatically detect the presence of application B and update both application A and application B so that the user doesn’t have to remember to run the site customizing software twice.
So far so good right? What’s the problem? Being a purist at heart the idea of having a site customizer automatically update 2 separate products immediately runs afoul of my instincts. But instincts are not evidence and unless you’ve really developed an intuition for these things they aren’t compelling arguments. Put another way, until you develop an intuition for design many conceptual objections will tend to be unpersuasive.
This being a project in the real world we quickly moved on to other problems. Fortunately everyone was ok with not having the site customization software automatically update the 2 products.
Why fortunately? Given a little time to think about it (in between long-running builds) it occured to me: What if product B has already been independently updated at the time the site customizer is run? It could end up overwriting newer data with an older version of the data. One of the benefits of having product B as a separate product was that it allowed us to get functionality out in the field in a way that didn’t require updating every product in the suite.
Of course this objection could be handled by the site customizer; it could check to make sure that it isnt overwriting a newer version of the data with an older version. However, doing this well would require the data to carry along its own version information. This is information that it currently doesn’t have. This kind of version information often requires a system of its own to maintain since a file can go for many releases without any changes. Without an automated system it’s yet another task to be forgotten during the often hectic process of releasing an upgraded version of software.
Versioning can be a pain but it’s not insurmountable. Another objection is that it creates a dependency between the site customizer and the 2 specific products it was supposed to automatically update. In computerese, the proposal raises the coupling between the site customizer and the customized applications. Product B can no longer change its location (e.g., to support side-by-side installation) without breaking the site customizing program.
The cascade of issues resulting from a proposal that tends to fight against the nature of the underlying things is a design smell.
Another approach that provides the desired convenience without fighting against the nature of the products involved is to have a separate program/script/process that invokes the site customization program twice.
What’s the difference between putting this intelligence into the site customizer or having it invoked externally? For one putting it in a separate program provides an opportunity to make explicit to the user the fact that they’re customizing product A and product B. Several months down the road the fact that customizing product A automatically customizes product B may be forgotten (and lead to the unintended data corruption mentioned above).
Recall that the site customizer, initially intended to customize product B, has already been drafted into customizing product A. It won’t be long before it’s customizing product C, D, etc…
Having a separate program invoke the customizer will tend to encourage a design that easily accommodates customizing more than 1 product. This kind of parameterization (loose coupling) of the customizer will make it that much easier to apply to products C, D, E, etc…
All of these benefits could have been lost, or made much more expensive, had we ignored the conceptual incongruence of making a relatively general purpose customizer try to do too much.