A conditional like if(isFreeVersion)
should occur just once in the code. This is not a pattern, but I am sure you already know the name for it: it is called the DRY principle. Having code like "if(isFreeVersion)
" in more than one place in your code means you repeated this line / the logic in it, which means it should be refactored to avoid the repetition.
"if(isFreeVersion)
" should be used to set up a list of internal configuration options for different features. The resulting code then could look like this:
if(isFreeVersion)
{
feature1Enabled=false;
feature2Enabled=false;
maxNoOfItems=5;
advertisingStrategy=new ShowLotsOfAdvertisementsStrategy();
// ...
}
else
{
feature1Enabled=true;
feature2Enabled=true;
maxNoOfItems=int.MaxValue; // virtually unlimited
advertisingStrategy=new ShowMinimalAdvertisementsStrategy();
}
This maps your single "isFreeVersion" flag to different features. Note you can decide here if you prefer to use individual boolean flags for individual features, or use some kind of other parameters, for example different strategy objects with a common interface, if the feature control requires a more complex parametrization.
Now you have your the control of what is in the free version and what in the paid version in one place, which makes maintenance of this logic quite simple. You will still have to be careful for not having your code cluttered with lots of if(feature1Enabled)
statements (by following the DRY principle), but now maintenance of this checks is not that painful any more. For example, you have much better control of what you need to change when you want to make an existing paid feature free (or vice versa).
Finally let us have a look into Fowler's blog article about feature toggles, where he speaks about feature entry points / toggle points. Let me cite one central point:
Don't try to protect every code path in the new feature code with a toggle, focus on just the entry points that would lead users there and toggle those entry points.
So as an overall strategy, focus on the user interface and restrict your checks to the minimal number of points there required to make a certain feature appear or disappear. That should keep your code base clean, without any unnecessary clutter.
if
checks to hide controls for forbidden features or having popup dialog for when user tries to do what he is not allowed to. I am hoping to find a way to avoid many conditionals in code