I've asked myself this question and I'm still not done thinking about this.
What I am thinking about
When you have a strategy pattern, a lot of implementations also use a factory pattern to retrieve a specific strategy. Most factory examples on the internet make use of a switch or if statement. This works perfectly when you do not often change or add strategies. But what if the factory is used to dynamically find a strategy and the strategies are changed and added often. Then this is a full time job for the programmer. Now I have a situation where I just want to add a new strategy without having to change the factory. In other words how do you implement the factory pattern so it dynamically searches for a strategy. And how can I list all available strategies.
The problem
When I look for this on the internet I can't find a good proper solution. I am thinking about using a reflection library to do this but it is not recommended to use reflection everywhere I look. So how to implement a dynamic factory. Or is there an other pattern for this purpose?
Example
The strategies:
The factory:
public enum StrategyName { ImplementedStrategy1, ImplementedStrategy2, ImplementedStrategy3 };
public class StrategyFactory
{
public static Sniffer getInstance(StrategyName choice) {
Strategy strategy = null;
switch (choice) {
case StrategyName.ImplementedStrategy1:
strategy = new ImplementedStrategy1();
break;
case StrategyName.ImplementedStrategy2:
strategy = new ImplementedStrategy2();
break;
case StrategyName.ImplementedStrategy3:
strategy = new ImplementedStrategy3();
break;
}
return strategy;
}
}
Now how can I make this dynamic? Or why shouldn't I?
Have your ImplementedStrategy
contract include a IsGoodMatch(params)
method. Then you just iterate over your collection of strategies, calling IsGoodMatch
on each one until you get one (or many) results, and then you use that strategy(ies).
I am not sure if this will help but here is what i am thinking. You have
public class ImplementedStrategy1 : Strategy
{
}
public class ImplementedStrategy2 : Strategy
{
}
etc..
Then you make an attribute class [StrategyName(StrategyName.EnumValue)]. More details here https://msdn.microsoft.com/en-us/library/aa288454(v=vs.71).aspx
So, now we get
[StrategyName(StrategyName.EnumValue1)].
public class ImplementedStrategy1 : Strategy
{
}
[StrategyName(StrategyName.EnumValue2)].
public class ImplementedStrategy2 : Strategy
{
}
Then, in public static Sniffer getInstance(StrategyName choice) instead of the switch,using reflection, you get all the types that inherit from Strategy and check if the choice parameter matches the custom attribute value.
Now you just need to create a new instance for that type.
When this is done and you wish to add a new strategy, you just have to create the new class with the attribute and add a new value to the enum.
Let me know if you need any help with the implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With