Состояние (State) — различия между версиями

Материал из Вики ИТ мехмата ЮФУ
Перейти к: навигация, поиск
(Описание)
(Варианты)
 
(не показано 11 промежуточных версий этого же участника)
Строка 5: Строка 5:
  
 
=== Описание ===
 
=== Описание ===
 +
При каждом изменении состояния объект-Контекст меняет свой подобъект состояния ConcreteState.
  
 +
Именно ConcreteState реализует обработку запроса.
  
 
=== Использование ===
 
=== Использование ===
 +
Паттерн используется когда поведение объекта зависит от состояния, которое может меняться.
 +
 +
Если в коде операций встречаются состоящие из многих ветвей условные операторы, где выбор ветви зависит от состояния, , то использование паттерна Состояние позволяет избавиться от этой тяжеловесной конструкции, поместив каждую ветвь в отдельный класс.
  
 
=== Реализация ===
 
=== Реализация ===
 
==== Диаграмма классов ====
 
==== Диаграмма классов ====
[[Изображение:.png|.png]]
+
[[Изображение:StateCommon.png]]
  
 
==== Участники====
 
==== Участники====
*
+
* '''Context''' - контекст
 +
** Определяет интерфейс, интересный для клиентов
 +
** Хранит экземпляр класса ConcreteState
 +
* '''State''' - состояние
 +
** Определяет интерфейс поведения, связанного с конкретным состоянием (метод Handle())
 +
* '''ConcreteState''' - конкретное состояние
 +
** Реализует интерфейс Handle()
 +
 
 +
Класс Context хранит объект ConcreteState и делегирует ему зависящие от состояния запросы.
 +
 
 +
Контекст может передавать себя в качестве параметра методу Handle() объекта State, обрабатывающего запрос.
 +
 
 +
Либо Context либо ConcreteState могут решать, каким образом происходит смена состояний.
 +
 
 +
=== Код ===
 +
<source lang="Csharp">
 +
abstract class State
 +
{
 +
    public abstract void Handle(Context context);
 +
}
 +
 
 +
class ConcreteStateA : State
 +
{
 +
    public override void Handle(Context context)
 +
    {
 +
        context.State = new ConcreteStateB();
 +
    }
 +
}
 +
 
 +
class ConcreteStateB : State
 +
{
 +
    public override void Handle(Context context)
 +
    {
 +
        context.State = new ConcreteStateA();
 +
    }
 +
}
 +
 
 +
class Context
 +
{
 +
    public Context(State state)
 +
    {
 +
        this.State = state;
 +
    }
  
==== Диаграмма последовательности ====
+
    public State State
[[Изображение:.png]]
+
    {
 +
        get; set;
 +
    }
  
=== Пример ===
+
    public void Request()
 +
    {
 +
        State.Handle(this);
 +
    }
 +
}
 +
</source>
  
 
=== Достоинства и недостатки ===
 
=== Достоинства и недостатки ===
*  
+
* Реализует зависящее от состояния поведение и делит его на части, соответствующие состояниям. Помещает поведение, связанное с конкретным состоянием, в отдельный объект. Добавление новых состояний достигается порождением новых подклассов класса state.
 +
* Ликвидирует ветвление, которое возникает в обычной реализации.
 +
* Делает явным переход между состояниями (при изменении переменной состояния)
 +
* Действия в зависимости от состояния разбросаны по многим классам, и за этим может быть трудно следить.
  
 
=== Варианты ===
 
=== Варианты ===
*
+
* Вместо того чтобы возлагать ответственность за переход в другое состояние на обработчик текущего состояния, можно использовать таблицу для отображения входных данных на переходы между состояниями (конечный автомат)
 +
* Ненужные уже объекты состояния можно уничтожать

Текущая версия на 10:30, 22 июля 2014

К основной странице курса

Назначение

Позволяет объекту менять своё поведение в зависимости от состояния. Состояние моделируется абстрактным объектом с множеством подобъектов (состояний).

Описание

При каждом изменении состояния объект-Контекст меняет свой подобъект состояния ConcreteState.

Именно ConcreteState реализует обработку запроса.

Использование

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

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

Реализация

Диаграмма классов

StateCommon.png

Участники

  • Context - контекст
    • Определяет интерфейс, интересный для клиентов
    • Хранит экземпляр класса ConcreteState
  • State - состояние
    • Определяет интерфейс поведения, связанного с конкретным состоянием (метод Handle())
  • ConcreteState - конкретное состояние
    • Реализует интерфейс Handle()

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

Контекст может передавать себя в качестве параметра методу Handle() объекта State, обрабатывающего запрос.

Либо Context либо ConcreteState могут решать, каким образом происходит смена состояний.

Код

abstract class State
{
    public abstract void Handle(Context context);
}

class ConcreteStateA : State
{
    public override void Handle(Context context)
    {
        context.State = new ConcreteStateB();
    }
}

class ConcreteStateB : State
{
    public override void Handle(Context context)
    {
        context.State = new ConcreteStateA();
    }
}

class Context
{
    public Context(State state)
    {
        this.State = state;
    }

    public State State
    {
        get; set;
    }

    public void Request()
    {
        State.Handle(this);
    }
}

Достоинства и недостатки

  • Реализует зависящее от состояния поведение и делит его на части, соответствующие состояниям. Помещает поведение, связанное с конкретным состоянием, в отдельный объект. Добавление новых состояний достигается порождением новых подклассов класса state.
  • Ликвидирует ветвление, которое возникает в обычной реализации.
  • Делает явным переход между состояниями (при изменении переменной состояния)
  • Действия в зависимости от состояния разбросаны по многим классам, и за этим может быть трудно следить.

Варианты

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