Студопедия
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

Паттерн State

Читайте также:
  1. Altai State Technological University.
  2. Analysis for this excerpt: There are idioms in this sentence. «State pair» – in this sentence means favorite glasses, which aunt Polly used to wear only when she went out.
  3. BACKGROUND INFORMATION ON THE UNITED STATES OF AMERICA.
  4. Britain, Europe and the United States
  5. CHAPTER 66 Armed With Sword, Yale-Perez Goes To A Feast Alone; For The State, Empress Finch Offers Her Life.
  6. CHAPTER 69 McGregor-Durkee Sees Things In The Book Of Changes; Five Loyal Subjects Die For Their State.
  7. Characterize the attitude of the British to sport. Complete the given passage, making use of the following word combinations from the box. Extend the statements.
  8. Christianity: the partnership of Church and state
  9. Chronic carrier state
  10. Church and state

Q табличная альтернатива. Том Каргилл (Tom Cargill) в книге C++Programming Style [Car92] описывает другой способ структурирования кода, управляе­мого сменой состояний. Он использует таблицу для отображения входных данных на переходы между состояниями. С ее помощью можно определить, в какое состояние нужно перейти при поступлении некоторых входных дан­ных. По существу, тем самым мы заменяем условный код (или виртуальные функции, если речь идет о паттерне состояние) поиском в таблице. Основное преимущество таблиц - в их регулярности: для изменения крите­риев перехода достаточно модифицировать только данные, а не код. Но есть и недостатки:

- поиск в таблице часто менее эффективен, чем вызов функции (виртуальной);

- представление логики переходов в однородном табличном формате делает
критерии менее явными и, стало быть, более сложными для понимания;

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

Главное различие между конечными автоматами на базе таблиц и паттерном состояние можно сформулировать так: паттерн состояние моделирует по­ведение, зависящее от состояния, а табличный метод акцентирует внимание на определении переходов между состояниями;

Q создание и уничтожение объектов состояния. В процессе разработки обыч­но приходится выбирать между:

- созданием объектов состояния, когда в них возникает необходимость,
и уничтожением сразу после использования;

- созданием их заранее и навсегда.

Первый вариант предпочтителен, когда заранее неизвестно, в какие состоя­ния будет попадать система, и контекст изменяет состояние сравнительно редко. При этом мы не создаем объектов, которые никогда не будут исполь­зованы, что существенно, если в объектах состояния хранится много инфор­мации. Когда изменения состояния происходят часто, поэтому не хотелось бы уничтожать представляющие их объекты (ибо они могут очень скоро по­надобиться вновь), следует воспользоваться вторым подходом. Время на создание объектов затрачивается только один раз, в самом начале, а на уничтожение - не затрачивается вовсе. Правда, этот подход может оказать­ся неудобным, так как в контексте должны храниться ссылки на все состоя­ния, в которые система теоретически может попасть;

Q использование динамического наследования. Варьировать поведение по за­просу можно, меняя класс объекта во время выполнения, но в большинстве объектно-ориентированных языков это не поддерживается. Исключение со­ставляет Self [US87] и другие основанные на делегировании языки, которые предоставляют такой механизм и, следовательно, поддерживают паттерн со­стояние напрямую. Объекты в языке Self могут делегировать операции


Паттерны поведения

другим объектам, обеспечивая тем самым некую форму динамического насле­дования. С изменением целевого объекта делегирования во время выполнения, по существу, изменяется и структура графа наследования. Такой механизм по­зволяет объектам варьировать поведение путем изменения своего класса.

Пример кода

В следующем примере приведен код на языке C++ с TCP-соединением из раз­дела «Мотивация». Это упрощенный вариант протокола TCP, в нем, конечно же, представлен не весь протокол и даже не все состояния TCP-соединений.1

Прежде всего определим класс TCPConnection, который предоставляет ин­терфейс для передачи данных и обрабатывает запросы на изменение состояния:

class TCPOctetStream; class TCPState;

class TCPConnection { public:

TCPConnection ();

void ActiveOpen (); void PassiveOpenO; void Close ();

void Send();

void Acknowledge ();

void Synchronize ();

void ProcessOctet (TCPOctetStream*); private:

friend class TCPState;

void ChangeState (TCPState*); private:

TCPState* _state;

};

В переменной-члене _state класса TCPConnection хранится экземпляр класса TCPState. Этот класс дублирует интерфейс изменения состояния, опре­деленный в классе TCPConnect ion. Каждая операция TCPState принимает экземп­ляр TCPConnection как параметр, тем самым позволяя объекту TCPState получить доступ к данным объекта TCPConnection и изменить состояние соединения:

class TCPState { public:

virtual void Transmit(TCPConnection*, TCPOctetStream*);

virtual void ActiveOpen(TCPConnection*);

virtual void PassiveOpen(TCPConnection*);

virtual void Close(TCPConnection*);

1 Пример основан на описании протокола установления TCP-соединений, приведенном в книге Лин­ча и Роуза [LR93]. %


Паттерн State

virtual void Synchronize (TCPConnection*);

virtual void Acknowledge (TCPConnection*); virtual void Send (TCPConnect ion*); protected:

void ChangeState (TCPConnection*, TCPState*);

TCPConnection делегирует все зависящие от состояния запросы хранимому в _state экземпляру TCPState. Кроме того, в классе TCPConnection существу­ет операция, с помощью которой в эту переменную можно записать указатель на другой объект TCPState. Конструктор класса TCPConnection инициализирует _state указателем на состояние TCPClosed (мы определим его ниже):

TCPConnection:: TCPConnection () {

_state = TCPClosed:: Instance ();

 

void TCPConnection::ChangeState (TCPState* s) { _state = s;

void TCPConnection::ActiveOpen () { _state->ActiveOpen(this);

void TCPConnection::PassiveOpen () { _state->PassiveOpen(this);

oid TCPConnection::Close () { _state->Close(this);

void TCPConnection:Acknowledge () { _state->Acknowledge (this);

void TCPConnection::Synchronize () {

_state->Synchronize(this); }

В классе TCPState реализовано поведение по умолчанию для всех делегирован­ных ему запросов. Он может также изменить состояние объекта TCPConnection посредством операции ChangeState. TCPState объявляется другом класса TCPConnection, что дает ему привилегированный доступ к этой операции:

void TCPState::Transmit (TCPConnection*, TCPOctetStream*) { } void TCPState::ActiveOpen (TCPConnection*) { } void TCPState::PassiveOpen (TCPConnection*) { }


Паттерны поведения

void TCPState:: Close (TCPConnection*) { }

void TCPState:: Synchronize (TCPConnection*) { }

void TCPState::ChangeState (TCPConnection* t, TCPState* s) { t->ChangeState(s);

}

В подклассах TCPState реализовано поведение, зависящее от состояния. Со­единение TCP может находиться во многих состояниях: Established (установ­лено), Listening (прослушивание), Closed (закрыто) и т.д., и для каждого из них есть свой подкласс TCPState. Мы подробно рассмотрим три подкласса -TCPEstablished, TCPListen и TCPClosed:

class TCPEstablished: public TCPState { public:

static TCPState* Instanced;

virtual void Transmit (TCPConnection*, TCPOctetStream*); virtual void Close (TCPConnection*);

) /

class TCPListen: public TCPState { public:

static TCPState* Instance();

virtual void Send(TCPConnection*);

class TCPClosed: public TCPState { public:

static TCPState* Instanced;

virtual void ActiveOpen(TCPConnection*); virtual void PassiveOpen(TCPConnection*);

В подклассах TCPState нет никакого локального состояния, поэтому их мож­но разделять, так что потребуется только по одному экземпляру каждого класса. Уникальный экземпляр подкласса TCPState создается обращением к статичес­кой операции Instance.1

В подклассах TCPState реализовано зависящее от состояния поведение для тех запросов, которые допустимы в этом состоянии:

void TCPClosed::ActiveOpen (TCPConnection* t) { // послать SYN, получить SYN, ACK и т.д.

ChangeState(t, TCPEstablished::Instanced);




Дата добавления: 2015-09-11; просмотров: 76 | Поможем написать вашу работу | Нарушение авторских прав

Паттерн Memento | Участники | Паттерны поведения | Пример кода | Паттерн Memento | Паттерн Observer | Реализация | Гдд Паттерны поведения | Паттерн Observer | Паттерн Observer |


lektsii.net - Лекции.Нет - 2014-2025 год. (0.023 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав