Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to implement a factory that automatically finds a strategy

Tags:

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: enter image description here

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?

like image 611
botenvouwer Avatar asked Oct 20 '16 14:10

botenvouwer


2 Answers

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).

like image 156
GWLlosa Avatar answered Sep 22 '22 16:09

GWLlosa


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.

like image 23
Lidaranis Avatar answered Sep 24 '22 16:09

Lidaranis