Шаблон проектирования «состояние» двадцать лет спустя. Разница между паттернами Состояние и Стратегия в Java State состояние

В режиме государственного (государственного образца), поведение класса основывается на его статус изменился. Этот тип шаблонов проектирования относятся поведенческие модели.

В государственной модели, мы создаем объекты и различные поведенческие состояний наряду с состоянием объекта изменяется измененном представления контекста объекта.

введение

Намерение: Позволяет объекту изменять свое поведение во внутреннем состоянии изменяется, то объект появляется, чтобы изменить свой класс.

Главным образом решить: поведение объекта зависит от его состояния (атрибутов), и вы можете изменить его в соответствии с его государством, связанные с изменением поведения.

Когда использовать: Код содержит большое количество объектов, связанных со статусом условных операторов.

Как исправить: статус конкретных классов абстрактных вне.

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

Примеры применения: 1, играть в баскетбол игрок может иметь нормальное состояние, а не нормальное состояние и ненормальное состояние. 2, маркиза Yi Цзэн колокола, то "часы абстрактный интерфейс", "часы А" и другие конкретные состояния, специфическая среда "" китайские колокола (контекст).

Преимущества: 1, инкапсулирует правила преобразования. 2, перечислить возможные состояния, прежде чем перечисление государству необходимо определить статус видов. 3, все с поведением государства, связанных в класс, и вы можете легко добавить новое состояние, нужно только изменить состояние объекта может изменить поведение объектов. 4, что позволяет осуществить переход состояния логическое состояние объекта в одном, а не один огромный блок условных операторов. 5, позволяет использовать несколько объектов разделяют среду состояние объекта, тем самым уменьшая количество объектов в системе.

Недостатки: 1, Паттерн состояние использования связано с увеличением числа системных классов и объектов. 2, структура и реализация государственной формы являются более сложными, при неправильном использовании может вызвать путаницу структуру программы и код. 3, поддержка государственного образца "Открытый Закрытый принцип" не очень хорошо, вы можете переключать состояние государственной модели, добавляя новые классы нужно изменить статус лиц, ответственных за переходы состояний исходного кода, или не может перейти в новое состояние, и изменить состояние класс действовать также необходимо модифицировать исходный код соответствующего класса.

Сценарии использования: 1, с поведением изменения состояния и изменения сцены. 2, условный переход утверждение заменой.

Примечание: При использовании ограниченного государственного поведения путем государственного режима, а государство не более пяти.

реализация

Мы создадим интерфейс статуса и сущностигосударственный класс реализации интерфейсаState. Контекст представляет собой класс с определенным состоянием.

StatePatternDemo, мы демонстрируем использование объектовКонтекст Контекст класса и статуса, чтобы продемонстрировать изменение поведения в состоянии изменения.

Шаг 1

Создайте интерфейс.

State.java

Public interface State { public void doAction(Context context); }

Шаг 2

Создать класс сущностей, который реализует интерфейс.

StartState.java

Открытый класс StartState реализует государство { общественного недействительными DoAction (контекст Контекст) { System.out.println ("Игрок находится в стартовом состоянии"); context.setState (это); } общественного Строка ToString () { вернуть "начальное состояние"; } }

StopState.java

Public class StopState implements State { public void doAction(Context context) { System.out.println("Player is in stop state"); context.setState(this); } public String toString(){ return "Stop State"; } }

Шаг 3

Создание классаконтекста.

Context.java

Открытый класс {Context частное Государственное государство; общественный контекст () { состояние = NULL; } общественного недействительными SetState (Государственное государство) { this.state = состояние; } общенародного государства GetState () { возвращать состояние; } }

Шаг 4

Используйтеконтекст , чтобы увидеть поведение при изменении состояния измененийсостояния.

StatePatternDemo.java

Открытый класс StatePatternDemo { государственной статической силы основных (String ) {агдз Контекст Контекст = новый контекст (); StartState startState = новый StartState (); startState.doAction (контекст); System.out.println (context.getState () ToString ().); StopState stopState = новый StopState (); stopState.doAction (контекст); System.out.println (context.getState () ToString ().); } }

Шаг 5

Проверьте выход.

Игрок находится в стартовом состоянии Start государственный Игрок находится в состоянии останова остановленном

Состояние (англ. State ) - поведенческий шаблон проектирования. Используется в тех случаях, когда во время выполнения программы объект должен менять свое поведение в зависимости от своего состояния.

Назначение паттерна State

    Паттерн State позволяет объекту изменять свое поведение в зависимости от внутреннего состояния. Создается впечатление, что объект изменил свой класс.

    Паттерн State является объектно-ориентированной реализацией конечного автомата.

Решаемая проблема

Поведение объекта зависит от его состояния и должно изменяться во время выполнения программы. Такую схему можно реализовать, применив множество условных операторов: на основе анализа текущего состояния объекта предпринимаются определенные действия. Однако при большом числе состояний условные операторы будут разбросаны по всему коду, и такую программу будет трудно поддерживать.

Обсуждение паттерна State

Паттерн State решает указанную проблему следующим образом:

    Вводит класс Context, в котором определяется интерфейс для внешнего мира.

    Вводит абстрактный класс State.

    Представляет различные "состояния" конечного автомата в виде подклассов State.

    В классе Context имеется указатель на текущее состояние, который изменяется при изменении состояния конечного автомата.

Паттерн State не определяет, где именно определяется условие перехода в новое состояние. Существует два варианта: класс Context или подклассы State. Преимущество последнего варианта заключается в простоте добавления новых производных классов. Недостаток заключается в том, что каждый подкласс State для осуществления перехода в новое состояние должен знать о своих соседях, что вводит зависимости между подклассами.

Структура паттерна State

Класс Context определяет внешний интерфейс для клиентов и хранит внутри себя ссылку на текущее состояние объекта State. Интерфейс абстрактного базового класса State повторяет интерфейс Context за исключением одного дополнительного параметра - указателя на экземплярContext. Производные от State классы определяют поведение, специфичное для конкретного состояния. Класс "обертка" Context делегирует все полученные запросы объекту "текущее состояние", который может использовать полученный дополнительный параметр для доступа к экземпляру Context.

UML-диаграмма классов паттерна State

Пример паттерна State

Паттерн State позволяет объекту изменять свое поведение в зависимости от внутреннего состояния. Похожая картина может наблюдаться в работе торгового автомата. Автоматы могут иметь различные состояния в зависимости от наличия товаров, суммы полученных монет, возможности размена денег и т.д. После того как покупатель выбрал и оплатил товар, возможны следующие ситуации (состояния):

    Выдать покупателю товар, выдавать сдачу не требуется.

    Выдать покупателю товар и сдачу.

    Покупатель товар не получит из-за отсутствия достаточной суммы денег.

    Покупатель товар не получит из-за его отсутствия.

Реализация

Рисунок 1. Диаграмма классов паттерна Состояние.

Паттерн состоит из 3 блоков:

    Widget – класс, объекты которого должны менять свое поведение в зависимости от состояния.

    IState – интерфейс, который должен реализовать каждое из конкретных состояний. Через этот интерфейс объект Widget взаимодействует с состоянием, делегируя ему вызовы методов. Интерфейс должен содержать средства для обратной связи с объектом, поведение которого нужно изменить. Для этого используется событие (паттерн Publisher - Subscriber). Это необходимо для того, чтобы в процессе выполнения программы заменять объект состояния при появлении событий. Возможны случаи, когда сам Widget периодически опрашивает объект состояние на наличие перехода.

    StateA … StateZ – классы конкретных состояний. Должны содержать информацию о том, при каких условиях и в какие состояния может переходить объект из текущего состояния. Например, из StateA объект может переходить в состояние StateB и StateC, а из StateB – обратно в StateA и так далее. Объект одного из них должен содержать Widget при создании.

public interface IState

event StateHandler NextState;

void SomeMethod();

public interface IWidget

void SomeMethod();

public class StateA: IState

public void SomeMethod()

Console.WriteLine("StateA.SomeMethod");

if (NextState != null)

NextState(new StateB());

public class StateB: IState

public event StateHandler NextState;

public void SomeMethod()

Console.WriteLine("StateB.SomeMethod");

if (NextState != null)

NextState(new StateA());

public delegate void StateHandler(IState state);

public class Widget: IWidget

public Widget(IState state)

OnNextState(state);

private void OnNextState(IState state)

if (state == null)

throw new ArgumentNullException("state");

if (State != state)

State.NextState += new StateHandler(OnNextState);

private IState state;

public void SomeMethod()

state.SomeMethod();

public IState State

get { return state; }

set { state = value; }

Рассмотрим пример:

IWidget widget = new Widget(new StateA());

widget.SomeMethod();

widget.SomeMethod();

При создании объекта Widget через параметр конструктора передается объект, инкапсулирующий состояние. Это состояние будет являться текущим, на его событие NextState подписывается метод OnNextState(), который заменяет state на присланный объект состояния. При вызове метода SomeMethod() в первый раз объект Widget делегирует этот вызов объекту StateA. После того, как метод StateA.SomeMethod() выполнился, объект вызовет событие NextState и передаст в параметр объект StateB, который заменяет текущее состояние StateA. При вызове SomeMethod() второй раз будет вызван StateB.SomeMethod(). То есть формально вызывается один и тот же метод, но его поведение различно.

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

Последнее обновление: 31.10.2015

Состояние (State) - шаблон проектирования, который позволяет объекту изменять свое поведение в зависимости от внутреннего состояния.

Когда применяется данный паттерн?

    Когда поведение объекта должно зависеть от его состояния и может изменяться динамически во время выполнения

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

UML-диаграмма данного шаблона проектирования предлагает следующую систему:

Формальное определение паттерна на C#:

Class Program { static void Main() { Context context = new Context(new StateA()); context.Request(); // Переход в состояние StateB context.Request(); // Переход в состояние StateA } } abstract class State { public abstract void Handle(Context context); } class StateA: State { public override void Handle(Context context) { context.State = new StateB(); } } class StateB: State { public override void Handle(Context context) { context.State = new StateA(); } } class Context { public State State { get; set; } public Context(State state) { this.State = state; } public void Request() { this.State.Handle(this); } }

Участники паттерна

    State : определяет интерфейс состояния

    Классы StateA и StateB - конкретные реализации состояний

    Context : представляет объект, поведение которого должно динамически изменяться в соответствии с состоянием. Выполнение же конкретных действий делегируется объекту состояния

Например, вода может находиться в ряде состояний: твердое, жидкое, парообразное. Допустим, нам надо определить класс Вода, у которого бы имелись методы для нагревания и заморозки воды. Без использования паттерна Состояние мы могли бы написать следующую программу:

Class Program { static void Main(string args) { Water water = new Water(WaterState.LIQUID); water.Heat(); water.Frost(); water.Frost(); Console.Read(); } } enum WaterState { SOLID, LIQUID, GAS } class Water { public WaterState State { get; set; } public Water(WaterState ws) { State = ws; } public void Heat() { if(State==WaterState.SOLID) { Console.WriteLine("Превращаем лед в жидкость"); State = WaterState.LIQUID; } else if (State == WaterState.LIQUID) { Console.WriteLine("Превращаем жидкость в пар"); State = WaterState.GAS; } else if (State == WaterState.GAS) { Console.WriteLine("Повышаем температуру водяного пара"); } } public void Frost() { if (State == WaterState.LIQUID) { Console.WriteLine("Превращаем жидкость в лед"); State = WaterState.SOLID; } else if (State == WaterState.GAS) { Console.WriteLine("Превращаем водяной пар в жидкость"); State = WaterState.LIQUID; } } }

Вода имеет три состояния, и в каждом методе нам надо смотреть на текущее состояние, чтобы произвести действия. В итоге с трех состояний уже получается нагромождение условных конструкций. Да и самим методов в классе Вода может также быть множество, где также надо будет действовать в зависимости от состояния. Поэтому, чтобы сделать программу более гибкой, в данном случае мы можем применить паттерн Состояние:

Class Program { static void Main(string args) { Water water = new Water(new LiquidWaterState()); water.Heat(); water.Frost(); water.Frost(); Console.Read(); } } class Water { public IWaterState State { get; set; } public Water(IWaterState ws) { State = ws; } public void Heat() { State.Heat(this); } public void Frost() { State.Frost(this); } } interface IWaterState { void Heat(Water water); void Frost(Water water); } class SolidWaterState: IWaterState { public void Heat(Water water) { Console.WriteLine("Превращаем лед в жидкость"); water.State = new LiquidWaterState(); } public void Frost(Water water) { Console.WriteLine("Продолжаем заморозку льда"); } } class LiquidWaterState: IWaterState { public void Heat(Water water) { Console.WriteLine("Превращаем жидкость в пар"); water.State = new GasWaterState(); } public void Frost(Water water) { Console.WriteLine("Превращаем жидкость в лед"); water.State = new SolidWaterState(); } } class GasWaterState: IWaterState { public void Heat(Water water) { Console.WriteLine("Повышаем температуру водяного пара"); } public void Frost(Water water) { Console.WriteLine("Превращаем водяной пар в жидкость"); water.State = new LiquidWaterState(); } }

Таким образом, реализация паттерна Состояние позволяет вынести поведение, зависящее от текущего состояния объекта, в отдельные классы, и избежать перегруженности методов объекта условными конструкциями, как if..else или switch. Кроме того, при необходимости мы можем ввести в систему новые классы состояний, а имеющиеся классы состояний использовать в других объектах.

«Паттерн State» источник.ru

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

Условия, Задача, Назначение

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

Мотивация

Рассмотрим класс TCPConnection , с помощью которого представлено сетевое соединение. Объект этого класса может находиться в одном из нескольких состояний: Established (установлено), Listening (прослушивание), Closed (закрыто). Когда объект TCPConnection получает запросы от других объектов, то в зависимости от текущего состояния он отвечает по-разному. Например, ответ на запрос Open (открыть) зависит от того, находится ли соединение в состоянии Closed или Established . Паттерн состояние описывает, каким образом объект TCPConnection может вести себя по-разному, находясь в различных состояниях. сайт источник оригинал сайт

Основная идея этого паттерна заключается в том, чтобы ввести абстрактный класс TCPState для представления различных состояний соединения. Этот класс объявляет интерфейс, единый для всех классов, описывающих различные рабочие оригинал источник.ru

состояния. В этих подклассах TCPState реализуется поведение, специфичное для конкретного состояния. Например, в классах TCPEstablished и TCPClosed реализовано поведение, характерное для состояний Established и Closed соответственно. сайт сайт оригинал источник

оригинал.ru

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

А при каждом изменении состояния соединения TCPConnection изменяет свой объект-состояние. Например, когда установленное соединение закрывается, TCPConnection заменяет экземпляр класса TCPEstablished экземпляром TCPClosed . сайт оригинал источник сайт

Признаки применения, использования паттерна Состояние (State)

Используйте паттерн состояние в следующих случаях: источник.ru
  1. Когда поведение объекта зависит от его состояния и при этом должно изменяться во время выполнения. источник оригинал.ru
  2. Когда в коде операций встречаются состоящие из многих ветвей условные операторы, в которых выбор ветви зависит от состояния. Обычно в таком случае состояние представлено перечисляемыми константами. Часто одна и та же структура условного оператора повторяется в нескольких операциях.Паттерн состояние предлагает поместить каждую ветвь в отдельный класс. Это позволяет трактовать состояние объекта как самостоятельный объект, который может изменяться независимо от других. сайт источник оригинал сайт

Решение

сайт сайт оригинал источник

источник.ru

Участники паттерна Состояние (State)

источник.ru
  1. Context (TCPConnection) - контекст.
    Определяет единый интерфейс для клиентов.
    Хранит экземпляр подкласса ConcreteState , которым определяется текущее состояние. codelab.
  2. State (TCPState) - состояние.
    Определяет интерфейс для инкапсуляции поведения, ассоциированного с конкретным состоянием контекста Context. сайт источник сайт оригинал
  3. Подклассы ConcreteState (TCPEstablished, TCPListen, TCPClosed) - конкретное состояние.
    Каждый подкласс реализует поведение, ассоциированное с некоторым состоянием контекста Context . сайт оригинал источник сайт

Схема использования паттерна Состояние (State)

Класс Context делегирует запросы текущему объекту ConcreteState . сайт оригинал источник сайт

Контекст может передать себя в качестве аргумента объекту State , который будет обрабатывать запрос. Это дает возможность объекту-состоянию (ConcreteState ) при необходимости получить доступ к контексту. codelab.

Context - это основной интерфейс для клиентов. Клиенты могут конфигурировать контекст объектами состояния State (точнее ConcreteState ). Один раз сконфигурировав контекст, клиенты уже не должны напрямую связываться с объектами состояния (только через общий интерфейс State ). источник.ru

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

Вопросы, касающиеся реализации паттерна Состояние (State)

Вопросы, касающиеся реализации паттерна State: источник оригинал.ru
  1. Что определяет переходы между состояниями.
    Паттерн состояние ничего не сообщает о том, какой участник определяет условия (критерии) перехода между состояниями. Если критерии зафиксированы, то их можно реализовать непосредственно в классе Context . Однако в общем случае более гибкий и правильный подход заключается в том, чтобы позволить самим подклассам класса State определять следующее состояние и момент перехода. Для этого в класс Context надо добавить интерфейс, позволяющий из объектов State установить его состояние.
    Такую децентрализованную логику переходов проще модифицировать и расширять - нужно лишь определить новые подклассы State . Недостаток децентрализации в том, что каждый подкласс State должен «знать» еще хотя бы об одном подклассе другого состояния (на которое собственно он и сможет переключить текущее состояние), что вносит реализационные зависимости между подклассами. сайт источник сайт оригинал

    источник оригинал.ru
  2. Табличная альтернатива.
    Существует еще один способ структурирования кода, управляемого сменой состояний. Это принцип конечного автомата. Он использует таблицу для отображения входных данных на переходы между состояниями. С ее помощью можно определить, в какое состояние нужно перейти при поступлении некоторых входных данных. По существу, тем самым мы заменяем условный код поиском в таблице.
    Основное преимущество автомата - в его регулярности: для изменения критериев перехода достаточно модифицировать только данные, а не код. Но есть и недостатки:
    - поиск в таблице часто менее эффективен, чем вызов функции,
    - представление логики переходов в однородном табличном формате делает критерии менее явными и, стало быть, более сложными для понимания,
    - обычно трудно добавить действия, которыми сопровождаются переходы между состояниями. Табличный метод учитывает состояния и переходы между ними, но его необходимо дополнить, чтобы при каждом изменении состоянии можно было выполнять произвольные вычисления.
    Главное различие между конечными автоматами на базе таблиц и Паттерн состояние можно сформулировать так: Паттерн состояние моделирует поведение, зависящее от состояния, а табличный метод акцентирует внимание на определении переходов между состояниями. оригинал.ru

    сайт оригинал источник сайт
  3. Создание и уничтожение объектов состояния.
    В процессе разработки обычно приходится выбирать между:
    - созданием объектов состояния, когда в них возникает необходимость, и уничтожением сразу после использования,
    - созданием их заранее и навсегда.

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

    источник.ru оригинал
  4. Использование динамического изменения.
    Варьировать поведение по запросу можно, меняя класс объекта во время выполнения, но в большинстве объектно-ориентированных языков это не поддерживается. Исключение составляет Perl, JavaScript и другие основанные на скриптовом движке языки, которые предоставляют такой механизм и, следовательно, поддерживают Паттерн состояние напрямую. Это позволяет объектам варьировать поведение путем изменения кода своего класса. источник.ru

    .ru источник оригинал

Результаты

Результаты использования паттерна состояние : оригинал.ru источник
  1. Локализует зависящее от состояния поведение.
    И делит его на части, соответствующие состояниям. Паттерн состояние помещает все поведение, ассоциированное с конкретным состоянием, в отдельный объект. Поскольку зависящий от состояния код целиком находится в одном из подклассов класса State , то добавлять новые состояния и переходы можно просто путем порождения новых подклассов.
    Вместо этого можно было бы использовать данные-члены для определения внутренних состояний, тогда операции объекта Context проверяли бы эти данные. Но в таком случае похожие условные операторы или операторы ветвления были бы разбросаны по всему коду класса Context . При этом добавление нового состояния потребовало бы изменения нескольких операций, что затруднило бы сопровождение. Паттерн состояние позволяет решить эту проблему, но одновременно порождает другую, поскольку поведение для различных состояний оказывается распределенным между несколькими подклассами State . Это увеличивает число классов. Конечно, один класс компактнее, но если состояний много, то такое распределение эффективнее, так как в противном случае пришлось бы иметь дело с громоздкими условными операторами.
    Наличие громоздких условных операторов нежелательно, равно как и наличие длинных процедур. Они слишком монолитны, вот почему модификация и расширение кода становится проблемой. Паттерн состояние предлагает более удачный способ структурирования зависящего от состояния кода. Логика, описывающая переходы между состояниями, больше не заключена в монолитные операторы if или switch , а распределена между подклассами State . При инкапсуляции каждого перехода и действия в класс - состояние становится полноценным объектом. Это улучшает структуру кода и проясняет его назначение. оригинал.ru
  2. Делает явными переходы между состояниями.
    Если объект определяет свое текущее состояние исключительно в терминах внутренних данных, то переходы между состояниями не имеют явного представления; они проявляются лишь как присваивания некоторым переменным. Ввод отдельных объектов для различных состояний делает переходы более явными. Кроме того, объекты State могут защитить контекст Context от рассогласования внутренних переменных, поскольку переходы с точки зрения контекста - это атомарные действия. Для осуществления перехода надо изменить значение только одной переменной (объектной переменной State в классе Context ), а не нескольких. источник.ru
  3. Объекты состояния можно разделять.
    Если в объекте состояния State отсутствуют переменные экземпляра, то есть представляемое им состояние кодируется исключительно самим типом, то разные контексты могут разделять один и тот же объект State . Когда состояния разделяются таким образом, они являются, по сути дела, приспособленцами (см. паттерн-приспособленец), у которых нет внутреннего состояния, а есть только поведение. сайт источник оригинал сайт

Пример

Рассмотрим реализацию примера из раздела « », т.е. построение некоторой простенькой архитектуры TCP соединения. Это упрощенный вариант протокола TCP, в нем, конечно же, представлен не весь протокол и даже не все состояния TCP-соединений. источник.ru оригинал

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

В переменной-члене state класса TCPConnection хранится экземпляр класса TCPState . Этот класс дублирует интерфейс изменения состояния, определенный в классе TCPConnection . оригинал.ru источник

сайт оригинал источник сайт

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

источник.ru оригинал

Каждая операция TCPState принимает экземпляр TCPConnection как параметр, тем самым, позволяя объекту TCPState получить доступ к данным объекта TCPConnection и изменить состояние соединения. .ru

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

оригинал.ru

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

Ru источник

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

сайт оригинал источник сайт

После выполнения специфичных для своего состояния действий эти операции источник оригинал.ru

вызывают ChangeState для изменения состояния объекта TCPConnection . У него же самого нет никакой информации о протоколе TCP. Именно подклассы TCPState определяют переходы между состояниями и действия, диктуемые протоколом. оригинал.ru

источник оригинал.ru

Известные применения паттерна Состояние (State)

Ральф Джонсон и Джонатан Цвейг характеризуют паттерн состояние и описывают его применительно к протоколу TCP.
Наиболее популярные интерактивные программы рисования предоставляют «инструменты» для выполнения операций прямым манипулированием. Например, инструмент для рисования линий позволяет пользователю щелкнуть в произвольной точке мышью, а затем, перемещая мышь, провести из этой точки линию. Инструмент для выбора позволяет выбирать некоторые фигуры. Обычно все имеющиеся инструменты размещаются в палитре. Работа пользователя заключается в том, чтобы выбрать и применить инструмент, но на самом деле поведение редактора варьируется при смене инструмента: посредством инструмента для рисования мы создаем фигуры, при помощи инструмента выбора - выбираем их и т.д. сайт сайт оригинал источник

Чтобы отразить зависимость поведения редактора от текущего инструмента, можно воспользоваться паттерном состояние . оригинал источник.ru

Можно определить абстрактный класс Tool , подклассы которого реализуют зависящее от инструмента поведение. Графический редактор хранит ссылку на текущий объект Too l и делегирует ему поступающие запросы. При выборе инструмента редактор использует другой объект, что приводит к изменению поведения. .ru

Данная техника используется в каркасах графических редакторов HotDraw и Unidraw. Она позволяет клиентам легко определять новые виды инструментов. В HotDraw класс DrawingController переадресует запросы текущему объекту Tool . В Unidraw соответствующие классы называются Viewer и Tool . На приведенной ниже диаграмме классов схематично представлены интерфейсы классов Tool

оригинал.ru

Позволяет объекту варьировать свое поведение в зависимости от внутреннего состояния. Извне создается впечатление, что изменился класс объекта.

Паттерн «Состояние» предполагает выделение базового класса или интерфейса для всех допустимых операций и наследника для каждого возможного состояния

Когда использовать Паттерн State

    Когда поведение объекта должно зависеть от его состояния и может изменяться динамически во время выполнения

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

UML схема паттерна "Состояние":

Реализация шаблона "состояние" на C#

using System; namespace DoFactory.GangOfFour.State.Structural { /// /// MainApp startup class for Structural /// State Design Pattern. /// class MainApp { /// /// Entry point into console application. /// static void Main() { // Setup context in a state Context c = new Context(new ConcreteStateA()); // Issue requests, which toggles state c.Request(); c.Request(); c.Request(); c.Request(); // Wait for user Console.ReadKey(); } } /// /// The "State" abstract class /// abstract class State { public abstract void Handle(Context context); } /// class ConcreteStateA: State { public override void Handle(Context context) { context.State = new ConcreteStateB(); } } /// /// A "ConcreteState" class /// class ConcreteStateB: State { public override void Handle(Context context) { context.State = new ConcreteStateA(); } } /// /// The "Context" class /// class Context { private State _state; // Constructor public Context(State state) { this.State = state; } // Gets or sets the state public State State { get { return _state; } set { _state = value; Console.WriteLine("State: " + _state.GetType().Name); } } public void Request() { _state.Handle(this); } } }

Пример паттерна State из реальной жизни

Примеры в.NET Framework

  • CommunicationObject реализует конечный автомат перехода между состояниями WCF клиента: Created, Opening, Opened, Closing, Closed и Faulted.
  • Task реализует конечный автомат перехода между состояниями задачи: Created, WaitingForActivation, WaitingToRun, Running, Run ToCompletion, Canceled, Faulted.