C# 如何为策略模式动态调用函数?
我正在使用.NETCoreWithRazorPages(MVVM)开发一个Web应用程序,用户可以在其中为我提供4个选项 这些选项中的每一个都执行相同的操作,但在执行方面有一点不同——这就是我想要实现策略模式的原因 有没有办法以某种方式动态生成函数名?这可能是一个愚蠢的问题,但我只是理解基本的问题C# 如何为策略模式动态调用函数?,c#,asp.net,design-patterns,C#,Asp.net,Design Patterns,我正在使用.NETCoreWithRazorPages(MVVM)开发一个Web应用程序,用户可以在其中为我提供4个选项 这些选项中的每一个都执行相同的操作,但在执行方面有一点不同——这就是我想要实现策略模式的原因 有没有办法以某种方式动态生成函数名?这可能是一个愚蠢的问题,但我只是理解基本的问题 // option = A // option = B // option = C // option = D public async Task<IActionResult> OnPo
// 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)
}
...
}
//选项=A
//选项=B
//选项=C
//选项=D
公共异步任务OnPostAsync()
{
...
var option=Input.option//from model
如果(选项==“A”){
A.DoAlgorithm(输入)
}否则,如果(选项=“B”){
B.DoAlgorithm(ïnput)
}否则,如果(选项=“c”){
C.DoAlgorithm(输入)
}否则{
D.DoAlgorithm(输入)
}
...
}
如果我这样做的话,我觉得我错过了这个模式的要点,所以我的问题是:是否有一些方法可以基于输入选项动态调用函数?如果我使用了错误的模式,请纠正我 您可以使用一个工厂,根据所选选项创建策略,然后使用一个基本策略类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");
}
}
}
虽然您可以按照“四人帮”策略模式死记硬背,但现在有其他工具可以做同样的事情,而无需创建工厂,也无需依赖继承子类或实现接口的类的激增,例如,由于函数现在可以用作变量,我们可以根据您的输入类型提供
操作
的地图:
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")
...
};
然后调用将如下所示:
public async Task<IActionResult> OnPostAsync()
{
if (HandlerMap.TryGetValue(option, out var algorithm))
{
algorithm(input);
}
// .. else this isn't a valid option.
}
公共异步任务OnPostAsync()
{
if(HandlerMap.TryGetValue(选项,输出var算法))
{
算法(输入);
}
//…否则这不是一个有效的选项。
}
谢谢您的回答。这似乎解决了我的问题,尽管下面的答案也是一个不错的选择。出于好奇,在推理和使用方面——为什么这个实现(没有设计模式)会比实际的更好?代码更少——GoF策略是在20世纪90年代制定的,当时函数式编程并不流行。Louis有下面的普通模式,您可以看到您需要一个接口(或基本/抽象类)、每个algo的多个子类(通常只有一个方法)、一个工厂(以创建正确的实例)。通常你也会想要抽象工厂,否则你只会得到原始的粗糙,只是工厂。本质上,任何只使用一个方法的
接口
抽象都可以用委托/Func/Action代替。保持简单:)因此,结果保持不变,但避免写得太多。谢谢你的解释。向上投票!:)显然,您可以增强/重构相当简单的算法查找步骤,即将if(HandlerMap.TryGetValue(option,out-var-algorithm))
移动到一个方法调用中,如FindMeTheAlgoForThisInput
,但您明白了。
public async Task<IActionResult> OnPostAsync()
{
if (HandlerMap.TryGetValue(option, out var algorithm))
{
algorithm(input);
}
// .. else this isn't a valid option.
}