как получить преимущество безгосударственной структуры - PullRequest
18 голосов
/ 10 марта 2011

Я хотел бы использовать http://code.google.com/p/stateless в своем коде, чтобы отделить функциональность от ее зависимостей. Я не нашел каких-либо продвинутых примеров использования, так что этот вопрос касается лучших практик фреймворка без сохранения состояния.

У меня следующая конфигурация (это только пример, только одно состояние функции):

var stateMachine = new StateMachine(State.Stopped);

stateMachine.Configure(State.Stopped)
    .Permit(Trigger.Failed, State.Error)
    .Permit(Trigger.Succeed, State.GenerateMachineData);

stateMachine.Configure(State.GenerateMachineData)
    .Permit(Trigger.Failed, State.Error)
    .Permit(Trigger.Succeed, State.Finished);

public enum State
{
    Stopped,
    GenerateMachineData,
    Finished,
    Error
}

public enum Trigger
{
    Succeed,
    Failed
}

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

1) Установите функциональность, а также следующий выстрел в OnEntry ():

stateMachine.Configure(State.GenerateMachineData)
.OnEntry(() => { 
    try {
       Generate(); 
       stateMachine.Fire(Trigger.Succeed);
    } catch {
       stateMachine.Fire(Trigger.Error);
    } 
})
.Permit(Trigger.Failed, State.Error)
.Permit(Trigger.Succeed, State.Finished);

так что если я просто позвоню

stateMachine.Fire(Trigger.Succeed);

заканчивается в State.Finished или State.Error

  • преимуществ - все вместе
  • Отклонения - решение не может быть действительно проверено

2) разделить машину состояний и функциональность следующим образом: <pre> void DoTheStuff() { switch (stateMachine.State) { State.Stopped: stateMachine.Fire(State.Succeed); break; State.GenerateMachineData: Generate(); stateMachine.Fire(State.Succeed); break; default: throw new Exception(); } }</p> <p>void Main() { while (stateMachine.State != State.Succeed && stateMachine.State != State.Error) { DoTheStuff(); } }

  • преимущества: состояние машины можно проверить самостоятельно
  • недостатки: мне совсем не нравится

3) какое-то другое решение?

Буду рад любому ответу

Ответы [ 2 ]

12 голосов
/ 13 мая 2011

Николас Блумхардт написал хороший пост о системе без гражданства.

9 голосов
/ 12 мая 2011

Мне нравится BugTrackerExample , который они имеют в исходном коде.

Так что ваша машина, вероятно, будет выглядеть так:

class Generator
{
    private readonly StateMachine state;

    public Generator()
    {
        state = new StateMachine(State.Stopped);

        // your definition of states ...

        state.Configure(State.GenerateMachineData)
        .OnEntry(() => { Generate(); })
        .Permit(Trigger.Failed, State.Error)
        .Permit(Trigger.Succeed, State.Finished);

        // ...
    }

    public void Succeed()
    {
        state.Fire(Trigger.Succeed);
    }

    public void Fail()
    {
        state.Fire(Trigger.Fail);
    }

    public void Generate()
    {
        // ...         
    }
}

В этом случае тесты не должныбыть проблемой.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...