Наиболее подходящий шаблон проектирования для реализации блок-схемы/модели

Мне нужно реализовать структуру блок-схемы на С#. Я передам данные первому узлу, он проверит некоторый элемент данных (логический), затем направит данные на один из двух последующих узлов и т. д.
Основной логический поток выглядит следующим образом:

  1. узел 1

    • If colour red goto node 2
    • иначе перейти к узлу 3
  2. узел 2

    • if weight 10 then goto node 4
    • иначе перейти к правилу 5
  3. узел 3

    • if size big then goto node 6
    • иначе перейти к узлу 10

так далее

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

Глядя на реализации паттерна CoR, кажется, что есть понятие NextHandler (Next Node), но не NextHandlerA и NextHandlerB — например.

Итак, если не CoR, какой шаблон лучше подходит для решения этой проблемы. Правила и последовательность могут часто меняться.

Спасибо за ваше время.


person jonho    schedule 13.07.2013    source источник


Ответы (1)


Шаблон состояния кажется подходящим. Вы можете смоделировать каждый из узлов в вашей системе как состояние.

Для начала ваш объект будет:

public class Object
{
    public string Color { get; set; }
    public int Weight { get; set; }
    public int Size { get; set; }

    private NodeState _state;
    public NodeState State { get { return _state; } set { _state = value; _state.Handle(); } }
}

Бизнес-логика проверки цвета, веса и т. д. будет находиться в соответствующих состояниях. Node1 будет выглядеть так:

public class Node1 : NodeState
{
    private readonly Object ctx;

    public Node1(Object ctx)
    {
        this.ctx = ctx;
    }

    public void Handle()
    {
        if (ctx.Color.Equals("Red"))
            ctx.State = new Node2(ctx);
        else
            ctx.State = new Node3(ctx);
    }
}

Для начала вы создадите объект и установите для него начальное состояние.

var obj = new Object(){Color = "Red", Weight = 10, Size = 5};
obj.State = new Node1(obj);

Передача всего объекта в узел может быть запахом. Вместо этого вы могли бы даже передать интерфейс.

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

Тем не менее, дизайн был бы достаточно расширяемым — в том смысле, что вы могли бы добавить больше узлов, если это необходимо, в соответствии с OCP (принцип открытия-закрытия).

person aquaraga    schedule 13.07.2013
comment
Я пришел, чтобы реализовать это прошлой ночью, и меня осенило, что я не смогу протестировать это, так как каждый раз создаю новый узел. как я могу подойти к этому, используя внедрение зависимостей? - person jonho; 15.07.2013
comment
Возможно, с помощью NodeFactory. Таким образом, вы могли бы сказать: ctx.State = factory.CreateNode2(ctx), и ваши тесты могли бы подтвердить взаимодействие с фабрикой. Метод Handle может принимать аргумент NodeFactory. - person aquaraga; 15.07.2013