Reputation: 39
I am working on a webapplication in .NET Core with Razor Pages (MVVM) with a form where the user can give me 4 options.
Each of those options perform the same action, but just a little bit different in terms of execution - that's why I'd like to implement the strategy pattern.
Is there a way to dynamically generate the function name in some way? It might be a silly question, but I just understand the basics.
// option = A
// option = B
// option = C
// option = D
public async Task<IActionResult> OnPostAsync()
{
...
var option = Input.Option // from model
if(option == "A") {
A.DoAlgorithm(input)
} else if(option = "B") {
B.DoAlgorithm(ïnput)
} else if(option = "c") {
C.DoAlgorithm(input)
} else {
D.DoAlgorithm(input)
}
...
}
It feels like I am missing the point here of this pattern if I would do this, so my question is: is there some way to dynamically call a function based on the input option? If I am using the wrong pattern for this, please do correct me.
Upvotes: 1
Views: 1742
Reputation: 107347
Although you could follow the Gang of Four strategy pattern rote, nowadays there are other tools to do much the same thing without creating factories, and relying on proliferation of classes which inherit subclasses or implementation interfaces, e.g. since functions can now be used as variables, we can provide a map of Action
s taking your input type:
public static readonly IDictionary<string, Action<InputType>> HandlerMap =
new Dictionary<string, Action<InputType>>
{
["A"] = DoAlgorithmA,
["B"] = DoAlgorithmB,
["C"] = DoAlgorithmC,
["D"] = (input) => Console.WriteLine("Too simple to need a method")
...
};
where InputType
is the type of your input
variable and DoAlgorithmA
etc are simply methods accepting InputType
(and if the methods are really concise, you could even use a lambda here), e.g.
public static void DoAlgorithmA(InputType input)
{
...
}
Invocation would then look like so:
public async Task<IActionResult> OnPostAsync()
{
if (HandlerMap.TryGetValue(option, out var algorithm))
{
algorithm(input);
}
// .. else this isn't a valid option.
}
Upvotes: 3
Reputation: 721
You can use a factory that creates the strategy based on the option chosen, then have a base strategy class that A,B,C and D extend to perform the specific instance of the algorithm.
Pseudo code:
interface Strategy
{
void DoAlgorithm()
}
class A : Strategy
{
}
class B : Strategy
{
}
abstract class Creator
{
public abstract Strategy FactoryMethod(string option);
}
class ConcreteCreator : Creator
{
public override Strategy FactoryMethod(string option)
{
switch (option)
{
case "A": return new A();
case "B": return new B();
default: throw new ArgumentException("Invalid type", "option");
}
}
}
Upvotes: 1