I have a class, called PolicyProvider, at present with the following (abridged) interface:
public interface IPolicyProvider
{
List<Policy> GetRenewalPolicies(Client client, int financialYear);
}
The purpose is quite obvious – every year, the insurance renews for the client, and they will get a number of new policies.
The thing is, the policies change year by year. Therefore, a concrete implementation of the class needs to be changed every year (or amended with lots of ugly little “if’s” evaluating the financial year). I can see that over time this will become horrendous.
In this case, what design pattern is most appropriate?
8
Following nulliusinverba
‘s suggestion, I’m creating an answer out of my original comment.
I see it as a scenario for a factory pattern, with your core PolicyFactory
(or provider) creating policies for any given client.
You could then in turn have a PolicyFactoryFactory
class, a factory of factories, that is (nevermind the awkward naming), capable of creating a PolicyFactory
for particular year (be it PolicyFactory2012
or PolicyFactory2013
etc.).
Obviously, this metafactory could still be able to parse external files and build policies out of their contents (as Florian suggested).
A standard approach to avoiding “if”s is to use subtyping and dynamic binding. All you need to do is to create subtype policies for each financial year.
1
You should use the Domain Model Pattern because “policies” (especially as you’ve described them) are subject to frequent change and you need to keep them sufficiently isolated so that you will not confuse or disrupt the “normal” path of execution.
Reasons to Use the Domain Model
In those cases where the behavior of the business is subject to a lot of change, having a domain model will decrease the total cost of those changes. Having all the behavior of the business that is likely to change encapsulated in a single part of our software decreases the amount of time we need to perform a change because it will all be performed in one place. By isolating that code as much as possible, we decrease the likelihood of changes in other places causing it to break, thus decreasing the time it takes to stabilize the system.