如何动态调用策略模式的函数?

时间:2018-05-30 15:33:23

标签: c# asp.net design-patterns

我正在使用Razor Pages(MVVM)在.NET Core中进行Web应用程序,其中一个表单可以为用户提供4个选项。

这些选项中的每一个都执行相同的操作,但在执行方面略有不同 - 这就是为什么我想实施策略模式。

有没有办法以某种方式动态生成函数名?这可能是一个愚蠢的问题,但我只是理解基础知识。

// 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) 
    }

    ...
}

如果我这样做,感觉我错过了这个模式的重点,所以我的问题是:有没有办法根据输入选项动态调用函数?如果我使用错误的模式,请纠正我。

2 个答案:

答案 0 :(得分:2)

虽然您可以遵循Gang of Four战略模式死记硬背,但现在还有其他工具可以在不创建工厂的情况下做同样的事情,并依赖于继承子类或实现接口的类的扩散,例如:由于函数现在可以用作变量,我们可以提供Action s的地图来获取您的输入类型:

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")
    ...
 };

其中InputTypeinput变量的类型,而DoAlgorithmA等只是接受InputType的方法(如果方法非常简洁,您甚至可以使用lambda here),例如

public static void DoAlgorithmA(InputType input)
{
    ...
}

调用看起来如此:

public async Task<IActionResult> OnPostAsync()
{
    if (HandlerMap.TryGetValue(option, out var algorithm))
    {
         algorithm(input);
    }
    // .. else this isn't a valid option.
}

答案 1 :(得分:1)

您可以使用根据所选选项创建策略的工厂,然后使用A,B,C和D扩展的基本策略类来执行算法的特定实例。

伪代码:

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");
 }
 }
}