2015-11-19 12 views
0

В какой ситуации мы должны принять государственный образец?В какой ситуации мы должны принять государственный образец?

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

Простой пример:

1. Исходное состояние "WAIT", ждать пользователя отправить команду загрузить

2. В то время как пользователь отправить скачать команду, перейти к "CONNECT" состояние, подключение к серверу

3. После того, как соединение создано, перейти к «Downloading» государству, продолжает получать данные от сервера

4. в то время как загрузка данных завершена, переходит к «Disconnect», отключите связь с сервером

5. После отключения, перейти к "WAIT" состояние, ждать пользователя отправить команду загрузки

A simple state machine pic

  • Метод 1: Перед тем, как обследование состояния модели, я думаю, что тривиальный метод --- обертка поведение разных состояний в разных функциях, используйте массив указателей функций для указания каждой функции состояния и изменения состояния по функции вызова.

    typedef enum { 
        WAIT, 
        CONNECT, 
        DOWNLOADING, 
        DISCONNECT 
    }state; 
    void (*statefunction[MAX_STATE])(void) = 
    { 
        WAITState, 
        CONNECTState, 
        DOWNLOADINGState, 
        DISCONNECTState 
    }; 
    void WAITState(void) 
    { 
        //do wait behavior 
        //while receive download command 
        //statefunction[CONNECT](); 
    } 
    void CONNECTState(void) 
    { 
        //do connect behavior 
        //while connect complete 
        //statefunction[DOWNLOADING](); 
    } 
    void DOWNLOADINGState(void) 
    { 
        //do downloading behavior 
        //while download complete 
        //statefunction[DISCONNECT](); 
    } 
    void DISCONNECTState(void) 
    { 
        //do disconnect behavior 
        //while disconnect complete 
        //statefunction[WAIT](); 
    } 
    
  • Способ 2: Паттерн состояния инкапсулирует другое состояние и его поведение в другом классе (объектно-ориентированный конечный автомате), использует полиморфизм для реализации различного государственного поведения, и определяет общий интерфейс для всех конкретных состояний.

    class State 
    { 
    public: 
        virtual void Handle(Context *pContext) = 0; 
    }; 
    class Context 
    { 
    public: 
        Context(State *pState) : m_pState(pState){} 
    
        void Request() 
        { 
         if (m_pState) 
         {    
          m_pState->Handle(this);   
         } 
        } 
    private: 
        State *m_pState; 
    }; 
    class WAIT : public State 
    { 
    public: 
        virtual void Handle(Context *pContext) 
        { 
         //do wait behavior 
        } 
    }; 
    class CONNECT : public State 
    { 
    public: 
        virtual void Handle(Context *pContext) 
        { 
         //do connect behavior 
        } 
    }; 
    class DOWNLOADING : public State 
    { 
    public: 
        virtual void Handle(Context *pContext) 
        { 
         //do downloading behavior 
        } 
    }; 
    class DISCONNECT : public State 
    { 
    public: 
        virtual void Handle(Context *pContext) 
        { 
         //do disconnect behavior 
        } 
    }; 
    

Я интересно ли состояние шаблон Тесто чем указатель функции в этом случае или нет ... Использование указателя функции только и может улучшить читаемость (сравните с выключателем случае), и более простой , Шаблон состояния создаст несколько классов и будет более сложным, чем использование только указателя функции. В чем преимущество использования шаблона состояния?

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

+0

«Шаблон состояния с несколькими классами» более полезен на языках, где вы не можете ссылаться на сами функции, такие как Java (<8), а скорее на * должны * использовать объекты. Вы можете просмотреть вариант указателя функции как реализацию шаблона, а вариант с несколькими классами как шаблон сам по себе, который работает с ограничениями языка (как это делают большинство «шаблонов»). – molbdnilo

+0

Связанный, если не дублированный вопрос: http://stackoverflow.com/questions/4935806/how-to-use-state-pattern-correctly/33676953#33676953 – Fuhrmanator

+0

* «Будет сложно расширить функцию, поэтому я хотел бы рефакторировать его »* - Вас попросили расширить его? Будут ли расширения новыми состояниями, новыми переходами или обоими? В вашем примере показан только один переход (Handle), но многие государственные машины имеют более одного. Версия OO (Method 2) требует, чтобы все состояния выполняли все переходы (поскольку они определены в классе 'State'). Добавьте несколько новых переходов или состояний, и вы увидите, что он становится очень быстрым. Если состояние не поддерживает переход, оно должно вызывать исключение, если этот метод вызывается. Это красивее вашего дела? – Fuhrmanator

ответ

0

В чем преимущество использования шаблона состояния?

Во-первых, нужно отметить, что как методов вы предоставили, являются фактически примеры тот же узор. Один из методов описывает функциональную реализацию , в то время как другая занимает больше объектно-ориентированного подхода.

Это, как говорится, сама модель имеет несколько преимуществ:

  1. Это ограничивает число государств, программа может быть в, и таким образом - устраняет неопределенные состояния,
  2. Это позволяет для более легкого расширения приложения, добавляя новые состояния, вместо рефакторинга весь код,
  3. с точки зрения компании, это безопасно, даже если несколько человек работают на том же классе,

Поскольку вы отметили вопрос как относящийся к , лучше всего учитывать то, что дает и требует язык. В то время как classes предлагают наследование, большое количество классов может значительно увеличить время компиляции. Следовательно, когда речь идет о реализации, если ваш конечный автомат большой, static polymorphism может быть путем.

 Смежные вопросы

  • Нет связанных вопросов^_^