На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Правила раздела:
1. Название темы - краткое описание кто/что против кого/чего
2. В первом сообщении - список параметров, по которым идет сравнение.
3. Старайтесь аргументировать свои высказывания. Фразы типа "Венда/Слюникс - ацтой" считаются флудом.
4. Давайте жить дружно и не доводить обсуждение до маразма и личных оскорблений.
Модераторы: Модераторы, Комодераторы
Страницы: (12) « Первая ... 8 9 [10] 11 12  все  ( Перейти к последнему сообщению )  
> Сохранение и восстановление состояния обработки
    Цитата Wound @
    Именно, оно уже выглядит пугающим. Когда там будет 100 лямбд - то уже будет на что посмотреть.

    Не, ну можно 100 классов объявить вместо лямбд, как два пальца об асфальт ;)
      Цитата Majestio @
      Не, ну можно 100 классов объявить вместо лямбд, как два пальца об асфальт ;)

      Фишка в том, что даже если будут 100 классов - они будут изолированы, и представлять собой конечную сущность, их можно оттестировать по отдельности например, представь что 100 человек написало по 1 классу. А с лямбдами сложнее выходит. Плюс лямбды твои, они у тебя гвоздями прибиты к переменной, объявленной в функции main -> A, а это очень херово.

      Добавлено
      Короче как по мне - даже первый твой вариант без GOTO, выигрывает по всем параметрам второй варинт с GOTO. И по читабельности кода, и по сопровождению. Потому что первый вариант можно и оттестировать, и расшрить без особых проблем. Второй вариант(который на лямбдах) - как по мне трешак, который придется полностью переписывать, если чуть условия усложнить.
        Цитата korvin @
        Цитата Qraizer @
        конечный автомат

        Гм, тогда к чему было:
        Цитата Qraizer @
        кажись, я слегка погорячился, прованговав всем известный паттерн.

        ?
        Я большей частью имел в виду хранение состояния через сериализацию. Как оно у кого будет реализовано, как бы без разницы. Я вот думал забабахать boost:serialisation, шоб вам тут мёдом не. :rolleyes:
        Цитата korvin @

        Ну да, он самый. Но вот как раз он у вас более-менее везде в той или иной форме. Опять же, какая разница, как его реализовывать. Нравится на switch(), та на здоровье, кому-то приспичило лямбдами его зарядить и переприсваивать их mainLoop, заодно лямбдами же и предикаты переходов оформить, тазарадибога.
        Я вот где-то видел универсальный автомат на шаблонах, который параметризировался переходами и действиями, реализованными функторами. Формально, весь автомат метакодируется ещё при компиляции. Думал порыскать по инету и применить у себя. То-то было бы весело сравнить с коленовелосипедными.
        Как я и говорил, для серьёзных задач всё это самое то, но для простых процессов накладные не оправдают расходы. Зато без goto, да. Круто, чё. Ну подумаешь, фрейморк будет отжирать 90% ресурсов.
        Сообщение отредактировано: Qraizer -
          Цитата Qraizer @
          Ну подумаешь, фрейморк будет отжирать 90% ресурсов.

          Не будет.

          Добавлено
          Хотя если под какие нибудь микроконтроллеры програмить, то там да - наверно надо за памятью следить. Просто с текущими тенденциями, я не знаю - что надо взять чтоб отжирать 90% ресурсов ))
            Цитата Wound @
            представь что 100 человек написало по 1 классу

            Представь что 100 человек написало по 1-й лямбде :P

            Цитата Wound @
            Плюс лямбды твои, они у тебя гвоздями прибиты к переменной, объявленной в функции main -> A, а это очень херово.

            А в лямбду можно еще параметры передавать :P а видимость всего внешнего запретить. А можно вообще функциями оформить. Но мне однострочные лямбды кажутся красивее однострочных функций.
              Цитата Qraizer @
              Я вот где-то видел универсальный автомат на шаблонах, который параметризировался переходами и действиями, реализованными функторами.

              Э-м… Так переходы и действия составляют 99% логики, что там в универсальной части? Цикл for?

              Цитата Wound @
              я не знаю - что надо взять чтоб отжирать 90% ресурсов ))

              Думаю, Qraizer имел в виду, что из всех ресурсов, потребляемых программой, 90% будут составлять накладные расходы на фреймворк.

              Цитата Wound @
              они будут изолированы, и представлять собой конечную сущность

              Не полностью: при добавлении нового процесса в твоём примере нужно будет:

              1) новый процесс прописать в каком-то decision'e (откуда он должен будет запускаться)
              Типа
              – был decision3Handler -> if true then Process2.Name …
              – должен стать decision3Handler -> if true then Process100.Name …

              2) старый процесс ( Process2.Name ) прописать куда-то в новое место
              И так далее, пока цепь не замкнётся.

              3) зарегистрировать новый процесс и decisionHandler в ProcessContext.

              4) Поправить тесты изменённых decision'ов.

              Итого из-за добавления одного процесса нужно править кучу классов. А как же SOLID?

              В наших же, с Majestio, примерах нужно править только один/два «класса» — switch-case и словарь «лямбд». И добавить тесты для новой лямбды (править тесты других decision'ов не нужно)

              Цитата Wound @
              их можно оттестировать по отдельности например

              Функции (лямбды) также прекрасно тестируются по-отдельности.

              Цитата Wound @
              Плюс лямбды твои, они у тебя гвоздями прибиты к переменной, объявленной в функции main -> A, а это очень херово.

              А если лямбды вынести из main в namespace challenge, будет менее херово?
                Эх. Надо будет хоть ваши варианты посмотреть как-нибудь, раз сам слился :)

                Кажется, у вас тут зарождается интересный спор.
                  Цитата D_KEY @
                  Кажется, у вас тут зарождается интересный спор.

                  Он тлеет ... и я вот думаю, подбросить дровишек или нет ... И больше думаю "да" :lol:

                  Смотрите какой вопрос

                  Приблизительно все наши решения сводились к таблице состояний и переходов вида:

                  StateProcessDescisionJump YesJump No
                  1P-1D-1J-11J-12
                  2P-2D-2J-21J-22
                  ...............
                  nP-nD-nJ-n1J-n2

                  1. Если вдруг нам нужен безусловный переход, тогда мы в D-i всегда возвращаем true, и всегда будем прыгать в J-i1 (ну или false и J-i2), вопросов нет
                  2. Если вдруг нам понадобится использовать P-i в нескольких местах, тоже проблем нет - просто в таблице переходов P-i будет повторяться, опять вопросов нет

                  Вопрос: а что делать, если вдруг, по каким-то соображениям, нам нужно организовать так, чтобы очередной D-i возвращал не true/false, а к примеру 0..17? Блок-схему алгоритма пересматривать, таблицу переходов модернизировать? Или что-то еще ... Ваши соображения? :rolleyes:
                    Цитата Wound @
                    Ну во первых мне честно лень добавлять еще 45 процессов. Это тупая копипаста получится. Схема от этого особо не изменится

                    Детализируй текущую схему на более мелкие шаги, делов-то.

                    Прикреплённая картинка
                    Прикреплённая картинка


                    Полноразмерное изображение: https://snipboard.io/87seH3.jpg

                    Добавлено
                    Цитата Majestio @
                    а что делать, если вдруг, по каким-то соображениям, нам нужно организовать так, чтобы очередной D-i возвращал не true/false, а к примеру 0..17?

                    Посмотри моё решение на Хаскелле и вопрос отпадёт сам собой.

                    Подсказка

                    Все процессы и проверки возвращают число: адрес следующего шага (state).

                    StateNameReturn State
                    0Stop0
                    1Process 15
                    2Process 26
                    3Process 37
                    4Process 45
                    5Decision 14|3
                    6Decision 23|4
                    7Decision 32|1
                    8Decision 40|2

                    Сообщение отредактировано: korvin -
                      Цитата korvin @
                      Посмотри моё решение на Хаскелле и вопрос отпадёт сам собой.

                      Да, объединение в одну таблицу и Process, и Decision - интересный вариант!
                      Тогда ветвления типа switch-case можно разложить на последовательные if-then-else вообще без накладных расходов.
                        Цитата korvin @
                        Не полностью: при добавлении нового процесса в твоём примере нужно будет:

                        Фигню не неси, а? Я щас тебе таких же шагов повысасываю из пальца. Потому что, что в моих примерах, что в его примерах - сделать нужно тоже самое.
                        В моем - добавляешь класс процесса, класс обработки решения, регистрируешь это в main. все. остальные детали идут из условия, у него это будет добавление лямбды во вторгой задаче, либо условия в switch.

                        Цитата korvin @
                        Итого из-за добавления одного процесса нужно править кучу классов. А как же SOLID?

                        Мне не нужно править кучу классов. Это ты из за того что не понимаешь что ты несешь, решил очередную чушь принести. И ничего там не нарушается.


                        Цитата korvin @
                        В наших же, с Majestio, примерах нужно править только один/два «класса» — switch-case и словарь «лямбд». И добавить тесты для новой лямбды (править тесты других decision'ов не нужно)

                        У него в решениях нет классов. Алё. И править ему придется ровно столько же, сколько и мне. Мде добавить 2 класса, и добавить их регистрацию, чтоб они вызвались. И ему две функции/лямбды. плюс добавить в его массив эти лямбды либо добавить case для первого пример.

                        Ты мне скажи - ты может быть количество строчек считаешь? Так прямо об этом и скажи тогда, а не виляй туда сюда.

                        Цитата korvin @
                        Функции (лямбды) также прекрасно тестируются по-отдельности.

                        Я комментирую написанный уже готовый код. Иди протестируй его лямбды, не изменяя его примера. Тут притензии не к лямбдам как таковым, а к тому как они юзаются.

                        Цитата korvin @
                        А если лямбды вынести из main в namespace challenge, будет менее херово?

                        То ты уже начнешь рефакторить его код, прям сходу.
                        Сообщение отредактировано: Qraizer -
                          Цитата Wound @

                          Ок
                            Цитата Wound @
                            Фигню не неси, а?

                            :facepalm:

                            Вот тебе схема с новым процессом:
                            Прикреплённая картинка
                            Прикреплённая картинка


                            Вот ТВОЙ код с добавлением нового процесса
                            ExpandedWrap disabled
                              using System;
                              using System.Collections.Generic;
                              using System.Linq;
                              using Challenge.Interfaces;
                               
                              //! Interfaces
                              namespace Challenge.Interfaces
                              {
                                  public interface IDecisionHandler
                                  {
                                      string HandleDecision(bool decision);
                                  }
                                  
                                  public interface IProcess
                                  {
                                      void Execute(List<int> values);
                                      bool Decision(List<int> values);
                                  }
                              }
                               
                               
                              namespace Challenge
                              {
                              //! DecisionhandlerContext
                                  public class DecisionHandlerContext
                                  {
                                      private Dictionary<string, IDecisionHandler> _handlers;
                                      public DecisionHandlerContext()
                                      {
                                          _handlers = new Dictionary<string, IDecisionHandler>();
                                      }
                               
                                      public void RegisterHandler(string processName, IDecisionHandler decisionHandler)
                                      {
                                          if (String.IsNullOrEmpty(processName) || decisionHandler == null)
                                              throw new Exception("Argument can't be null");
                               
                                          _handlers.Add(processName, decisionHandler);
                                      }
                               
                                      public string HandleDecisionAndGetNextStep(string processName, bool decision)
                                      {
                                          if (String.IsNullOrEmpty(processName))
                                              throw new Exception("Invalid arguments");
                               
                                          if(_handlers.TryGetValue(processName, out var handler))
                                          {
                                              return handler.HandleDecision(decision);
                                          }
                                          throw new Exception("Handle error");
                                      }
                                  }
                               
                                  public class Process1DecisionHandler : IDecisionHandler
                                  {
                                      public string HandleDecision(bool decision)
                                      {
                                          if(decision)
                                              return Process4.ProcessName;
                                          return Process3.ProcessName;
                                      }
                                  }
                               
                                  public class Process2DecisionHandler : IDecisionHandler
                                  {
                                      public string HandleDecision(bool decision)
                                      {
                                          if (decision)
                                              return Process3.ProcessName;
                                          return Process5.ProcessName;
                                      }
                                  }
                               
                                  public class Process3DecisionHandler : IDecisionHandler
                                  {
                                      public string HandleDecision(bool decision)
                                      {
                                          if (decision)
                                              return Process2.ProcessName;
                                          return Process1.ProcessName;
                                      }
                                  }
                               
                                  public class Process4DecisionHandler : IDecisionHandler
                                  {
                                      public string HandleDecision(bool decision)
                                      {
                                          if (decision)
                                              return Process6.ProcessName;
                                          return Process2.ProcessName;
                                      }
                                  }
                                  
                                  public class Process5DecisionHandler : IDecisionHandler
                                  {
                                      public string HandleDecision(bool decision)
                                      {
                                          if(decision)
                                              return Process4.ProcessName;
                                          return Process3.ProcessName;
                                      }
                                  }
                               
                                  public class Process6DecisionHandler : IDecisionHandler
                                  {
                                      public string HandleDecision(bool decision)
                                      {
                                          return String.Empty;
                                      }
                                  }
                                  
                              //! Process1
                                  public class Process1 : IProcess
                                  {
                                      private const int MaxSizeValues = 5;
                                      public static string ProcessName => "1";
                               
                                      public void Execute(List<int> values)
                                      {
                                          if (values == null || values.Count > MaxSizeValues)
                                              throw new InvalidOperationException("List of values is empty...");
                                          ++values[0];
                                      }
                               
                                      public bool Decision(List<int> values)
                                      {
                                          return (values.Sum() % 2) == 0;
                                      }
                               
                                  }
                               
                              //! Process2
                                  public class Process2 : IProcess
                                  {
                                      private const int MaxSizeValues = 5;
                                      public static string ProcessName => "2";
                               
                                      public bool Decision(List<int> values)
                                      {
                                          return (values.Sum() % 7) > 0;
                                      }
                               
                                      public void Execute(List<int> values)
                                      {
                                          if (values == null || values.Count > MaxSizeValues)
                                              throw new InvalidOperationException("List of values is empty...");
                               
                                          values[1] += values[3] + 1;
                                      }
                                  }
                               
                              //! Process3
                                  public class Process3 : IProcess
                                  {
                                      private const int MaxSizeValues = 5;
                                      public static string ProcessName => "3";
                               
                                      public bool Decision(List<int> values)
                                      {
                                          var existOdd = values.Any(e => e % 2 != 0);
                                          return !existOdd;
                                      }
                               
                                      public void Execute(List<int> values)
                                      {
                                          if (values == null || values.Count > MaxSizeValues)
                                              throw new InvalidOperationException("List of values is empty...");
                               
                                          if ( (values[0] + values[1]) % 3 > 0 )
                                              values[2] += 7;
                                      }
                                  }
                               
                              //! Process4
                                  public class Process4 : IProcess
                                  {
                                      private const int MaxSizeValues = 5;
                                      public static string ProcessName => "4";
                               
                                      public bool Decision(List<int> values)
                                      {
                                          return values.Sum() > 24;
                                      }
                               
                                      public void Execute(List<int> values)
                                      {
                                          if (values == null || values.Count > MaxSizeValues)
                                              throw new InvalidOperationException("List of values is empty...");
                               
                                          if ((values[0] + values[2]) % 5 != 4)
                                              ++values[3];
                                      }
                                  }
                               
                              //! Process4
                                  public class Process5 : IProcess
                                  {
                                      private const int MaxSizeValues = 5;
                                      public static string ProcessName => "5";
                               
                                      public bool Decision(List<int> values)
                                      {
                                          return values[4] > 0;
                                      }
                               
                                      public void Execute(List<int> values)
                                      {
                                          if (values == null || values.Count > MaxSizeValues)
                                              throw new InvalidOperationException("List of values is empty...");
                               
                                          ++values[4];
                                      }
                                  }
                               
                              //! Process6
                                  public class Process6 : IProcess
                                  {
                                      public static string ProcessName => "6";
                               
                                      public bool Decision(List<int> values)
                                      {
                                          return true;
                                      }
                               
                                      public void Execute(List<int> values)
                                      {
                                      }
                                  }
                               
                              //! ProcessContext
                                  public class ProcessContext
                                  {
                                      private Dictionary<string, IProcess> _processes;
                                      private DecisionHandlerContext _handlerContext;
                                      public ProcessContext()
                                      {
                                          _processes = new Dictionary<string, IProcess>();
                                          _handlerContext = new DecisionHandlerContext();
                                      }
                               
                                      public ProcessContext AddProcess(string proccesName, IProcess process, IDecisionHandler handler)
                                      {
                                          if (String.IsNullOrEmpty(proccesName) || process == null)
                                              throw new Exception("Argument can't be null");
                               
                                          _processes.Add(proccesName, process);
                                          _handlerContext.RegisterHandler(proccesName, handler);
                               
                                          return this;
                                      }
                               
                                      public bool RunProcessAndCheckDecision(string processName, List<int> values)
                                      {
                                          if(_processes.TryGetValue(processName, out var proc))
                                          {
                                              if (proc == null)
                                                  throw new Exception($"Process with name '{processName}' is null.");
                               
                                              proc.Execute(values);
                               
                                              return proc.Decision(values);
                                          }
                               
                                          throw new Exception($"Process with name '{processName}' not found.");
                                      }
                               
                                      public void RunAllProcesses(int step, string startProcessName, List<int> values)
                                      {
                                          string currentProcessName = startProcessName;
                                          while (true)
                                          {
                                              Console.WriteLine($"Step {step}\t Proc: {currentProcessName}\t {String.Join(" ", values)}");
                               
                                              var result = RunProcessAndCheckDecision(currentProcessName, values);
                                              currentProcessName = _handlerContext.HandleDecisionAndGetNextStep(currentProcessName, result);
                                              if (String.IsNullOrEmpty(currentProcessName))
                                                  break;
                                              ++step;
                                          }
                                      }
                                  }
                                  
                              //! Programm
                                  public class Program
                                  {
                                      static void Main(string[] args)
                                      {
                                          try
                                          {
                                              List<int> values = new List<int> { 0, 0, 0, 0, 0 };
                               
                                              ProcessContext processContext = new ProcessContext();
                               
                                              processContext
                                                  .AddProcess(Process1.ProcessName, new Process1(), new Process1DecisionHandler())
                                                  .AddProcess(Process2.ProcessName, new Process2(), new Process2DecisionHandler())
                                                  .AddProcess(Process3.ProcessName, new Process3(), new Process3DecisionHandler())
                                                  .AddProcess(Process4.ProcessName, new Process4(), new Process4DecisionHandler())
                                                  .AddProcess(Process5.ProcessName, new Process5(), new Process5DecisionHandler())
                                                  .AddProcess(Process6.ProcessName, new Process6(), new Process6DecisionHandler());
                               
                                              processContext.RunAllProcesses(1, Process1.ProcessName, values);
                               
                                              Console.WriteLine("--------------------------");
                                              List<int> savedValues = new List<int> { 3, 1, 14, 1, 0 };
                                              processContext.RunAllProcesses(9, Process2.ProcessName, savedValues);
                                          }
                                          catch(Exception error)
                                          {
                                              Console.WriteLine(error.Message);
                                          }
                                      }
                                  }
                              }

                            https://rextester.com/MWCA94654

                            Вот diff: https://quickdiff.net/?unique_id=C835D453-8...68-DBDE2D1B54C6

                            Что мы видим в данном изменении?

                            Цитата korvin @
                            1) новый процесс прописать в каком-то decision'e (откуда он должен будет запускаться)

                            Есть? Есть: прописали Process 5 в Process2DecisionHandler.

                            Цитата korvin @
                            2) старый процесс прописать куда-то в новое место

                            Есть? Нет: старый процесс 4 теперь вызывается из нового процесса. Если бы старый процесс нужно было бы перепривязать в другой старый процесс, то и тут было бы «Есть».

                            Цитата korvin @
                            3) зарегистрировать новый процесс и decisionHandler в ProcessContext.

                            Есть? Есть.

                            Цитата korvin @
                            4) Поправить тесты изменённых decision'ов.

                            Есть? Условно говоря, возможно. Тестов у тебя нет, если бы были, пришлось бы править тест Process2DecisionHandler, хотя сейчас Handler'ы выглядят тривиальными, не требующими тестирования.

                            Итого, в таком простом изменении 2 попадания, из которых одно (пункт 1) — прямое нарушение SOILD.

                            Как бонус, ты в своей «классной ООП-архитектуре» забыл абстрагировать ячейки памяти, в результате пришлось в каждом классе процесса править константу MaxSizeValues. Ещё одно нарушение SOILD.
                            Кстати, почему в методе Execute размер списка проверяется, а в методе Decision — нет?

                            Вот, например, изменения в версии на Ocaml, со switch-case-loop
                            ExpandedWrap disabled
                              module type Machine =
                                sig
                                  type data = int array
                                  val init : ?data:data -> unit -> unit
                                  val dump : unit -> data
                               
                                  type process = unit -> unit
                                  val process_1 : process
                                  val process_2 : process
                                  val process_3 : process
                                  val process_4 : process
                                  val process_5 : process
                               
                                  type decision = unit -> bool
                                  val decision_1 : decision
                                  val decision_2 : decision
                                  val decision_3 : decision
                                  val decision_4 : decision
                                  val decision_5 : decision
                                end
                               
                              module Program (M : Machine) =
                                struct
                               
                                  type state =
                                    | Proc_1
                                    | Proc_2
                                    | Proc_3
                                    | Proc_4
                                    | Proc_5
                                    | Stop
                               
                                  let ( --> ) = ( |> )
                               
                                  let yes y ~no:n decision = if decision then y else n
                               
                                  let rec run count state =
                                    log_state count state ;
                                    let loop = run (count + 1) in
                                    match state with
                                    | Proc_1 -> () --> M.process_1 --> M.decision_1 --> yes Proc_4 ~no:Proc_3 --> loop
                                    | Proc_2 -> () --> M.process_2 --> M.decision_2 --> yes Proc_3 ~no:Proc_5 --> loop
                                    | Proc_3 -> () --> M.process_3 --> M.decision_3 --> yes Proc_2 ~no:Proc_1 --> loop
                                    | Proc_4 -> () --> M.process_4 --> M.decision_4 --> yes Stop   ~no:Proc_2 --> loop
                                    | Proc_5 -> () --> M.process_5 --> M.decision_5 --> yes Proc_4 ~no:Proc_3 --> loop
                                    | Stop   -> ()
                               
                                  and log_state count state =
                                    let data = M.dump () in
                                    Printf.printf "Step: %2d   %s   %s\n" count (state_string state) (data_string data)
                               
                                  and state_string s =
                                    match s with
                                    | Proc_1 -> "Process 1"
                                    | Proc_2 -> "Process 2"
                                    | Proc_3 -> "Process 3"
                                    | Proc_4 -> "Process 4"
                                    | Proc_5 -> "Process 5"
                                    | Stop   -> "Stop     "
                               
                                  and data_string data =
                                    data --> Array.map (Printf.sprintf " %2d") --> Array.to_list --> String.concat " "
                               
                                end
                               
                               
                              module Majestio_machine : Machine =
                                struct
                               
                                  let size = 5
                               
                                  let cell = Array.make size 0
                               
                                  type data = int array
                               
                                  let init ?(data=[||]) () =
                                    let n = min size (Array.length data) in
                                    if n = 0
                                      then Array.fill cell 0 size 0
                                      else Array.blit data 0 cell 0 n
                               
                                  let dump () = Array.copy cell
                               
                                  type process = unit -> unit
                               
                                  let process_1 () =
                                    cell.(0) <- cell.(0) + 1
                               
                                  let process_2 () =
                                    cell.(1) <- cell.(1) + cell.(3) + 1
                               
                                  let process_3 () =
                                    let sum_0_1 = cell.(0) + cell.(1) in
                                    if sum_0_1 mod 3 <> 0 then
                                      cell.(2) <- cell.(2) + 7
                               
                                  let process_4 () =
                                    let sum_0_2 = cell.(0) + cell.(2) in
                                    if sum_0_2 mod 5 <> 4 then
                                      cell.(3) <- cell.(3) + 1
                               
                                  let process_5 () =
                                    cell.(4) <- cell.(4) + 1
                               
                                  type decision = unit -> bool
                               
                                  let sum = Array.fold_left (+) 0
                               
                                  let decision_1 () = sum cell mod 2 = 0
                               
                                  let decision_2 () = sum cell mod 7 > 0
                               
                                  let decision_3 () =
                                    let is_even x = x mod 2 = 0 in
                                    Array.for_all is_even cell
                               
                                  let decision_4 () = sum cell > 24
                               
                                  let decision_5 () = cell.(4) > 0
                               
                                end
                               
                               
                              let main () =
                                let module Machine = Majestio_machine in
                                let module Program = Program (Machine) in
                               
                                Machine.init () ;
                                Program.run 1 Program.Proc_1 ;
                                print_endline "----------------------------------------------------------------" ;
                               
                                Machine.init ~data:[| 3; 1; 14; 1; 0 |] () ;
                                Program.run 9 Program.Proc_2 ;
                                print_endline "----------------------------------------------------------------" ;
                               
                                print_endline "done"
                               
                              let () = main ()

                            https://rextester.com/WKONS22441

                            Вот diff: https://quickdiff.net/?unique_id=EDAE41DF-0...35-F78B02FB93DF

                            Как видно, никаких изменений в реализациях process_2 и decision_2 в модуле Majestio_machine нет. Из дополнительного только 1) изменение размера памяти и 2) изменение самого автомата в соответствие с изменившимися связями на схеме.

                            Таким образом, твои «независимые классы» независимы лишь иллюзорно, и твой код просто скрывает эти связи, запутывая читателя.
                            Сообщение отредактировано: Qraizer -
                              Цитата korvin @


                              Вот тебе схема с новым процессом:

                              Ааа, то есть изначально шла речь про просто добавление нового процесса, а теперь ты решил изменить условия всей задачи и других процессов, браво! Так тогда и тебе и majestio придется менять все условия. В чем вопрос, если ты изменил условия задачи?


                              Цитата korvin @
                              Вот diff: https://quickdiff.net/?unique_id=C835D453-8...68-DBDE2D1B54C6

                              Что мы видим в данном изменении?

                              Во первых ты там половину отсебятины добавил и переписал(зачем то, во вторых ты взял первый пример, в последнем примере там и так уже 5 процессов). Единственное что придется при добавлении нового процесса менять - это константу количества процессов. Мне лень было ее выносить куда то в отдельный базовый класс. И все. В данном случае - я прекрасно понимал что придется ее менять так же, при добавлении, но лень мне уже было ее выносить куда то.

                              Цитата korvin @
                              Есть? Есть: прописали Process 5 в Process2DecisionHandler.

                              Тогда ты так и пиши - "если я захочу изменить условия перехода для всех уже имеющихся процессов, тогда тебе придется изменять свои классы", а не "если я захочу добавить новый процесс, то тебе придется изменять уже существующие класса". Ты разницы не видишь или что?


                              Цитата korvin @
                              Есть? Есть.

                              Тебе придется в С++ коде делать ровно тоже самое, только это будет по другому называться. Я же говорю - ты из пальца высосал свои шаги, чтоб их было побольше желательно, причем все они будут так же у тебя.


                              Цитата korvin @
                              Итого, в таком простом изменении 2 попадания, из которых одно (пункт 1) — прямое нарушение SOILD.

                              Где тут нарушение S ?


                              Цитата korvin @
                              Как бонус, ты в своей «классной ООП-архитектуре» забыл абстрагировать ячейки памяти, в результате пришлось в каждом классе процесса править константу MaxSizeValues. Ещё одно нарушение SOILD.
                              Кстати, почему в методе Execute размер списка проверяется, а в методе Decision — нет?

                              А у меня не было написать какое то идеальное решение, я уверен в моем решении еще много косяков, но это решение - прекрасно масштабируется и сопровождается. С минимальными переделками основной логики программы.


                              Цитата korvin @
                              Как видно, никаких изменений в реализациях process_2 и decision_2 в модуле Majestio_machine нет. Из дополнительного только 1) изменение размера памяти и 2) изменение самого автомата в соответствие с изменившимися связями на схеме.

                              не не не, ты в свой код внес ровно те же самые изменения что и в мой(ну за исключением константы).
                              Ты добавил процесс, добавил какое то decision5 как ты там выразился,
                              Ты изменил вот эту соплю или что это(предполагаю это решение процесса2):
                              | Proc_2 -> () --> M.process_2 --> M.decision_2 --> yes Proc_3 ~no:Proc_5 --> loop

                              Опять же изменил константу. Т.е. ты внес плюс минус те же самые изменения. в свой код.
                                Цитата Wound @
                                Ааа, то есть изначально шла речь про просто добавление нового процесса, а теперь ты решил изменить условия всей задачи и других процессов, браво!

                                Какие условия задачи? По-твоему, новый процесс куда добавляется? В вакуум? Чтобы что? Чтобы просто так висел в сторонке?

                                Типа такого, да?
                                Прикреплённая картинка
                                Прикреплённая картинка


                                :facepalm:

                                Цитата Wound @
                                Во первых ты там половину отсебятины добавил

                                Что же там отсебятина?

                                Цитата Wound @
                                Тогда ты так и пиши - "если я захочу изменить условия перехода для всех уже имеющихся процессов, тогда тебе придется изменять свои классы", а не "если я захочу добавить новый процесс, то тебе придется изменять уже существующие класса". Ты разницы не видишь или что?

                                Что же, по-твоему, означает «добавление нового процесса»?

                                Цитата Wound @
                                Где тут нарушение S ?

                                Изменение двух классов по одной причине.

                                Цитата Wound @
                                Я же говорю - ты из пальца высосал свои шаги

                                Я тебе схему привёл, код и diff. Указанные изменения есть? Есть.

                                Цитата Wound @
                                не не не, ты в свой код внес ровно те же самые изменения что и в мой(ну за исключением константы).

                                Естественно. Ты не до конца прочитал мой пост, что ли?

                                Цитата Wound @
                                Ты добавил процесс, добавил какое то decision5 как ты там выразился,

                                Ага, добавил ровно то, что требовалось.

                                Цитата Wound @
                                Ты изменил вот эту соплю или что это(предполагаю это решение процесса2):

                                Это стрелки диаграммы, как они нарисованы на схеме, так они тут и написаны. Всё наглядно.

                                Цитата Wound @
                                Опять же изменил константу. Т.е. ты внес плюс минус те же самые изменения. в свой код.

                                Ага. Только не менял какой-то там Process2DecisionHandler, хрен пойми, где находящийся. )

                                Ещё раз перечитай последнее предложение:

                                Цитата korvin @
                                Таким образом, твои «независимые классы» независимы лишь иллюзорно, и твой код просто скрывает эти связи, запутывая читателя.

                                Как и «масштабируемость» твоя илюзорна.
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:
                                Страницы: (12) « Первая ... 8 9 [10] 11 12  все


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,1531 ]   [ 21 queries used ]   [ Generated: 25.06.24, 02:04 GMT ]