Реализация связи между этими классами - PullRequest
0 голосов
/ 23 ноября 2018

Я ищу советы о том, как лучше всего реализовать следующее:

У меня есть класс, который получает ввод, скажем, каждую секунду и запускает событие при получении этого ввода (отправляя вместе с ним информацию овходные данные).

Это событие подписано несколькими другими классами.
Каждый из этих классов имеет:

  • «ранжирование» (intполе),
  • метод bool Condition (который проверяет условие на основе входных данных события) и метод с именем run.

Когда событие вызывается, все классы вызывают метод Condition.при условии, что метод возвращает true, я бы хотел, чтобы метод run вызывался только для класса с самым высоким рейтингом.

Способ, которым я его реализую, - это когда событие вызывается, все классы добавляют ранжирование иметод run к списку (рейтинг 0 добавляется, если условие не выполняется).
Когда список достигает установленного значения, он выбирает самый высокий рейтинг и вызывает связанный метод.

Здесьэто код:

class mainClass
{
    void Input(int input)
    {
         goEvent?.Invoke(input);
    }

    public event Action<int> goEvent;

    public int TEMP_COUNTER=0;
    public int TEMP_RANK=0;
    public string TEMP_METHODNAME = "";
}

class class1
{
    //...
    int rank = 4;

    bool condition(int n)
    {
      if(n > 10)
          return true;
      else
          return false;
    }

    void run(){}

    void mainClassEventHandler(int input)
    {
        if (condition(input)
        {
            addtolist(rank,run)
        }
        else
        {
          addtolist(0,null)
        }
    }
}

class class2
{
    //...
    int rank = 3;

    bool condition(int n)
    {
        if(n > 20)
            return true;
        else
            return false;
    }

    void run(){}

    void mainClassEventHandler(int input)
    {
      if (condition(input)
          addtolist(rank,run)
      else
          addtolist(0,null)
    }
}

1 Ответ

0 голосов
/ 23 ноября 2018

Я не думаю, что модель подписки подходит для этой проблемы.Ваш "MainClass" должен больше функционировать как оркестратор (выбирая работающий наивысший рейтинг) для выполнения против вслепую, генерируя событие.

Итак, давайте начнем с интерфейса для ваших классов "бегуна":

  interface RankedRunner
  {
      // The rank of the runner (this must be immutable).
      int Rank { get; }

      // Whether we can run this runner.
      bool Runnable(int input);

      // Run the runner.
      void Run();
  }

Теперь давайте добавим несколько реализаций:

   class Runner1 : RankedRunner
    {
        public int Rank => 3;

        public void Run()
        {
        }

        public bool Runnable(int input)
        {
            return input > 20;
        }
    }

    class Runner2 : RankedRunner
    {
        public int Rank => 4;

        public void Run()
        {
        }

        public bool Runnable(int input)
        {
            return input > 10;
        }
    }

Наконец, давайте организуем вызов бегунов на основе некоторого ввода:

    class Orchestration
    {
        private SortedList<RankedRunner, RankedRunner> runners;

        Orchestration()
        {
            // We need to sort our runners based on their rank. If two runners
            // have the same rank then use the object comparator.
            // Note that x and y get swapped so the largest rank will be ordered first.
            this.runners = new SortedList<RankedRunner, RankedRunner>(
                Comparer<RankedRunner>.Create(
                    (x, y) =>
                    {
                        return x.Rank == y.Rank
                            ? Comparer<RankedRunner>.Default.Compare(y, x)
                            : Comparer<int>.Default.Compare(y.Rank, x.Rank);
                    }));
        }

        Orchestration addRankedRunner(RankedRunner runner)
        {
            this.runners.Add(runner, runner);
            return this;
        }

        void Input(int input)
        {  
            // Find the highest ranked runner that is runnable.
            foreach(RankedRunner runner in runners.Values)
            {
                if(runner.Runnable(input))
                {
                    runner.Run();
                    break;
                }
            }
        }
    }

Пример использования:

      var orchestration = new Orchestration();
        orchestration.addRankedRunner(new Runner1());
        orchestration.addRankedRunner(new Runner2());

        orchestration.Input(5);
        orchestration.Input(10);
        orchestration.Input(50);
...