В какой ситуации мы должны принять государственный образец?В какой ситуации мы должны принять государственный образец?
Я был назначен для поддержки проекта, конечный автозапуск проекта был реализован коммутационным корпусом длиной 2000+ строк. Будет сложно расширить функцию, поэтому я бы хотел ее реорганизовать. Я рассматриваю шаблон государственного образца, но у меня есть некоторые путаницы.
Простой пример:
1. Исходное состояние "WAIT", ждать пользователя отправить команду загрузить
2. В то время как пользователь отправить скачать команду, перейти к "CONNECT" состояние, подключение к серверу
3. После того, как соединение создано, перейти к «Downloading» государству, продолжает получать данные от сервера
4. в то время как загрузка данных завершена, переходит к «Disconnect», отключите связь с сервером
5. После отключения, перейти к "WAIT" состояние, ждать пользователя отправить команду загрузки
Метод 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 } };
Я интересно ли состояние шаблон Тесто чем указатель функции в этом случае или нет ... Использование указателя функции только и может улучшить читаемость (сравните с выключателем случае), и более простой , Шаблон состояния создаст несколько классов и будет более сложным, чем использование только указателя функции. В чем преимущество использования шаблона состояния?
Спасибо за ваше время!
«Шаблон состояния с несколькими классами» более полезен на языках, где вы не можете ссылаться на сами функции, такие как Java (<8), а скорее на * должны * использовать объекты. Вы можете просмотреть вариант указателя функции как реализацию шаблона, а вариант с несколькими классами как шаблон сам по себе, который работает с ограничениями языка (как это делают большинство «шаблонов»). – molbdnilo
Связанный, если не дублированный вопрос: http://stackoverflow.com/questions/4935806/how-to-use-state-pattern-correctly/33676953#33676953 – Fuhrmanator
* «Будет сложно расширить функцию, поэтому я хотел бы рефакторировать его »* - Вас попросили расширить его? Будут ли расширения новыми состояниями, новыми переходами или обоими? В вашем примере показан только один переход (Handle), но многие государственные машины имеют более одного. Версия OO (Method 2) требует, чтобы все состояния выполняли все переходы (поскольку они определены в классе 'State'). Добавьте несколько новых переходов или состояний, и вы увидите, что он становится очень быстрым. Если состояние не поддерживает переход, оно должно вызывать исключение, если этот метод вызывается. Это красивее вашего дела? – Fuhrmanator