In the previous post I worked through how to implement the strategy pattern and register multiple implementations of the same interface in the ASP.Net Core DI framework. In this post I want to look at another way of implementing the same pattern without having an enum applicable property but an IsApplicable
method.
Strategy update to use IsApplicable
To implement this idea I have updated the original post code and tweaked the IMathOperator
to have an IsApplicable
method instead of a public property which returns an enum.
public interface IMathOperator
{
bool IsApplicable(Operator op);
int Calculate(int a, int b);
}
I am still using an enum to determine whether it’s applicable or not but this could now be a struct or specific class instance which is passed through at the calling point.
For example AddOperator
now looks like this:
public class AddOperator : IMathOperator
{
public bool IsApplicable(Operator op)
{
return op == Operator.Add;
}
public int Calculate(int a, int b) => a + b;
}
Once now implemented in each of the operators I then had to change the MathStrategy
implementation to be able to handle the update.
public class MathStrategy : IMathStrategy
{
private readonly IEnumerable<IMathOperator> _operators;
public MathStrategy(IEnumerable<IMathOperator> operators)
{
_operators = operators;
}
public int Calculate(int a, int b, Operator op)
{
foreach (var @operator in _operators)
{
if (@operator.IsApplicable(op))
{
return @operator.Calculate(a, b);
}
}
throw new ArgumentNullException(nameof(op));
}
}
Extensions
In the above I am still only applying a single action per “operator” in other implementations you may have to remove the return
and exception throwing as multiple operators maybe applicable!
Conclusion
In this post we have looked at how to update the Strategy pattern implementation from the original post to not rely on an enum property but have an IsApplicable
method which allows for more complicated logic as to when an action should be applied. The updated code still uses an enum but is not required to.
A full working example can be found on Github.
Any questions/comments then please contact me on Twitter @WestDiscGolf