Как динамически вызывать функцию для шаблона стратегии? - PullRequest
0 голосов
/ 30 мая 2018

Я работаю над веб-приложением в .NET Core с Razor Pages (MVVM) с формой, в которой пользователь может предоставить мне 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 голосов
/ 30 мая 2018

Несмотря на то, что вы можете следовать шаблону стратегии «Банды четырех», в настоящее время существуют другие инструменты, позволяющие делать то же самое, не создавая фабрики и полагаясь на распространение классов, которые наследуют подклассы или интерфейсы реализации, например, поскольку теперь можно использовать функциив качестве переменных мы можем предоставить карту 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")
    ...
 };

, где InputType - это тип вашей input переменной, а DoAlgorithmA и т. д. - просто методы, принимающие InputType (и если методы действительно лаконичны, вы даже можете использовать лямбду здесь), например,

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.
}
0 голосов
/ 30 мая 2018

Вы можете использовать фабрику, которая создает стратегию на основе выбранной опции, а затем иметь базовый класс стратегии, который расширяется 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");
 }
 }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...