Видео курс по шаблонам проектирования. State - видео курсы ITVDN
ITVDN: курсы программирования
Видеокурсы по
программированию

    Выбери свою IT специальность

    Начать бесплатно

    Выбери свою IT специальность

    Начать бесплатно

      Видео курс по шаблонам проектирования

      ×

      Вы открыли доступ к тесту! Пройти тест

      Вы действительно хотите открыть доступ к тестированию по курсу Шаблоны проектирования на 40 дней?

      ВИДЕОУРОК №26. State

      Для просмотра полной версии видеокурса, онлайн тестирования и получения доступа к дополнительным учебным материалам купите курс Купить курс
      Для просмотра всех видеокурсов ITVDN, представленных в Каталоге, а также для получения доступа к учебным материалам и онлайн тестированию купите подписку Купить подписку
      В данном видео уроке рассматривается структура курса “Шаблоны проектирования” и производится краткий обзор книги “Приемы объектно-ориентированного проектирования. Паттерны проектирования” с обсуждением всех ее достоинств и недостатков. Также автор презентует книгу «Design Patterns via C#», которая в доходчивом, понятном и упрощенном виде объясняет назначение и применение паттернов в создании программного обеспечения.
      Читать дальше...
      Технически, паттерны (шаблоны) проектирования - это всего лишь абстрактные примеры правильного использования небольшого числа комбинаций простейших техник ООП. Видео урок представит простые примеры, показывающие правильные способы организации взаимодействий между классами или объектами.
      Читать дальше...
      Этот видео урок из "Курса шаблоны проектирования" посвящен UML (англ. Unified Modeling Language — унифицированный язык моделирования) — язык графического описания для объектного моделирования в области разработки программного обеспечения. UML является языком широкого профиля, это — открытый стандарт, использующий графические обозначения для создания абстрактной модели системы, называемой UML-моделью. Данный видеоурок познакомит вас c базовыми возможностями и подходами к проектированию с помощью языка UML.
      Читать дальше...
      Данный видео урок из курса "Шаблоны проектирования" познакомит Вас с понятием конечного автомата, вариантами его описания и логикой построения простейших конечных автоматов.
      Читать дальше...
      Видео урок раскроет понятие парадигмы программи́рования, которая является совокупностью идей и понятий, определяющих стиль написания компьютерных программ. Это способ концептуализации, определяющий организацию вычислений и структурирование работы, выполняемой компьютером. Этот видеоурок расскажет Вам об основных современных парадигмах объектно-ориентированного программирования, которые поддерживаются платформой .NET.
      Читать дальше...
      Данный видео урок дает базовые знания о регулярных грамматиках, и основных способах их применения в программировании.
      Читать дальше...
      Видео урок посвящен паттерну Abstract Factory, который предоставляет клиенту интерфейс (набор методов) для создания семейств взаимосвязанных или взаимозависимых объектов-продуктов, при этом скрывает от клиента информацию о конкретных классах этих объектов-продуктов.
      Читать дальше...
      Видеоурок посвящен паттерну проектирования Builder, который помогает организовать пошаговое построение сложного объекта-продукта так, что клиенту не требуется понимать последовательность шагов и внутреннее устройство строящегося объекта-продукта, при этом в результате одного и того же процесса конструирования могут получаться объекты-продукты с различным представлением (внутренним устройством).
      Читать дальше...
      Видео урок посвящен шаблону проектирования Factory Method, который предоставляет абстрактный интерфейс (набор методов) для создания объекта-продукта, но оставляет возможность, разработчикам классов, реализующих этот интерфейс самостоятельно принять решение о том, экземпляр какого конкретного класса-продукта создать. Паттерн Factory Method позволяет базовым абстрактным классам передать ответственность за создание объектов-продуктов своим производным классам.
      Читать дальше...
      Видеоурок расскажет о паттерне Prototype, который предоставляет возможность создания новых объектов-продуктов (клонов), используя технику клонирования (копирования) созданного ранее объекта-оригинала-продукта (прототипа). Паттерн Prototype – позволяет задать различные виды (классы-виды) объектов-продуктов (клонов), через настройку состояния каждого нового созданного клона. Классификация клонов-продуктов производится на основании различия их состояний.
      Читать дальше...
      Видео урок познакомит с шаблоном проектирования Singleton, который гарантирует, что у класса может быть только один экземпляр. В частном случае предоставляется возможность наличия, заранее определенного числа экземпляров.
      Читать дальше...
      Видео урок посвящен паттерну Adapter, он преобразует интерфейс (набор имен методов) одного класса в интерфейс (набор имен методов) другого класса, который ожидают клиенты. Адаптер обеспечивает совместную работу классов с несовместимыми интерфейсами, такая работа без Адаптера была бы невозможна.
      Читать дальше...
      Видео урок посвящен паттерну Bridge, который позволяет отделить абстракцию от элементов ее реализации так, чтобы и абстракцию, и реализацию можно было изменять независимо друг от друга.
      Читать дальше...
      Виде урок расскажет о шаблоне проектирования Composite, который составляет из объектов древовидные структуры для представления иерархий «часть – целое». Позволяет клиентам единообразно трактовать индивидуальные объекты (листья) и составные объекты (ветки).
      Читать дальше...
      Видео урок посвящен паттерну Decorator(декоратор), который динамически (в ходе выполнения программы) добавляет объекту новые возможности (состояние и/или поведение). Композиция, используемая при реализации паттерна Decorator, является гибкой альтернативой наследованию (порождению подклассов) с целью расширения функциональности.
      Читать дальше...
      Видео урок посвящен шаблону проектирования Facade, который предоставляет унифицированный интерфейс (набор имен методов) вместо интерфейса некоторой подсистемы (набора взаимосвязанных классов или объектов).
      Читать дальше...
      Видео урок посвящен шаблону проектированию Flyweight, который описывает правильное применение техники создания «разделяемых объектов», для получения возможности эффективного использования большого числа объектов.
      Читать дальше...
      Видео урок посвящен шаблону проектирования Proxy, который предоставляет объект-заместитель для контроля доступа к другому объекту.
      Читать дальше...
      Видео урок посвящен паттерну проектирования Chain of Responsibility, который позволяет избежать привязки объекта-отправителя запроса к объекту-получателю запроса, при этом давая шанс обработать этот запрос нескольким объектам. Паттерн Chain of Responsibility связывает в цепочку объекты-получатели запроса и передает запрос вдоль этой цепочки, пока один из объектов, составляющих эту цепочку не обработает передаваемый запрос.
      Читать дальше...
      Видео урок расскажет о шаблоне проектирования Command (Команда), который позволяет представить запрос в виде объекта, позволяя клиенту конфигурировать запрос (задавая параметры для его обработки), ставить запросы в очередь, протоколировать запросы, а также поддерживать отмену операций.
      Читать дальше...
      Видео урок посвящен шаблону проектирования Interpreter (интерпретатор), который позволяет сформировать объектно-ориентированное представление грамматики для заданного языка, а также описывает правила создания механизма интерпретации (толкования) предложений этого языка.
      Читать дальше...
      Видео урок посвящен шаблону проектирования Iterator (Итератор), который представляет удобный и безопасный способ доступа к элементам коллекции (составного объекта), при этом не раскрывая внутреннего представления этой коллекции.
      Читать дальше...
      Видео урок посвящен шаблону проектирования Mediator (посредник), который предоставляет объект-посредник, скрывающий способ взаимодействия множества других объектов-коллег. Объект-посредник обеспечивает слабую связанность системы, избавляя объектов-коллег от необходимости явно ссылаться друг на друга, позволяя тем самым независимо изменять взаимодействия между объектами-коллегами.
      Читать дальше...
      Видео урок посвящен поведенческому шаблоны проектирования Memento (хранитель), который не нарушая инкапсуляции, фиксирует и выносит за пределы объекта-хозяина его внутреннее состояние так, чтобы позднее это вынесенное состояние можно было восстановить в исходном объекте-хозяине.
      Читать дальше...
      Видео урок посвящен шаблону проектирования Observer (наблюдатель), который использует связь-отношения зависимости «один ко многим» (один издатель ко многим подписчикам). При изменении состояния одного объекта (издателя), все зависящие от него объекты (подписчики) оповещаются об этом и автоматически обновляются.
      Читать дальше...
      Видео урок расскажет о шаблоне проектирования State (Состояние), который позволяет объекту изменять свое поведение в зависимости от своего состояния. Поведение объекта изменяется на столько, что создается впечатление, что изменился класс объекта.
      Читать дальше...
      Видео урок посвящен шаблону проектирования Strategy (Стратегия), который определяет набор алгоритмов (часто схожих по роду деятельности), инкапсулирует каждый из имеющихся алгоритмов (в отдельный класс) и делает их подменяемыми. Паттерн Strategy позволяет подменять алгоритмы без участия клиентов, которые используют эти алгоритмы.
      Читать дальше...
      Видео урок посвящен паттерну проектирования Template Method, который формирует структуру алгоритма и позволяет в производных классах реализовать, заместить (перекрыть) или переопределить определенные шаги (участки) алгоритма, не изменяя структуру алгоритма в целом.
      Читать дальше...
      Видео урок посвящен шаблону проектирования Visitor (Посетитель), который позволяет единообразно обойти набор элементов с разнородными интерфейсами (т.е. набор объектов разных классов не приводя их к общему базовому типу), а также позволяет добавить новый метод (функцию) в класс объекта, при этом не изменяя сам класс этого объекта.
      Читать дальше...
      ПОКАЗАТЬ ВСЕ
      основные темы, рассматриваемые на уроке
      0:00:25
      Метафора
      0:02:55
      Структура паттерна на языке UML
      0:03:41
      Структура паттерна на языке C#
      0:06:40
      О понимании Конечного автомата (книга)
      0:08:30
      Назначение паттерна
      ПОКАЗАТЬ ВСЕ
      Рекомендуемая литература
      Рекомендуемой литературы к данному уроку не предусмотрено
      Титры видеоурока

      Паттерн State

      Название

      Состояние

      Также известен как

      FSM (Finite-State Machine) - КА (Конечный автомат или Машина состояний)

      Классификация

      По цели: поведенческий

      По применимости: к объектам

      Частота использования

      Средняя               -   1 2 3 4 5

      Назначение

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

      Введение

      Паттерн State описывает способы и правила построения объектно-ориентированного представления конечных автоматов (КА). Конечные автоматы классифицируются по логическим свойствам функций переходов и выходов, а также по характеру отсчёта дискретного времени.

      По способу формирования функций выходов выделяют автоматы Мили и Мура. У автоматов Мили функции выходов находятся на ребре, а у автоматов Мура функции выходов находятся в состоянии. По характеру отсчёта дискретного времени автоматы делятся на синхронные и асинхронные.

      Конечный автомат Мили

      Рассмотрим простейший тип конечно-автоматного преобразователя информации: Автомат Мили. Определим конечный автомат формально. Есть и другие определения, но мы остановимся на этом.

      Задавать автомат удобно графом, в котором вершины соответствуют состояниям, а ребро из состояния sn в состояние sm, помеченное x/y, проводится тогда, когда автомат из состояния sn под воздействием входного сигнала x переходит в состояние sm с выходной реакцией y.

      ПРИМЕР:

      Зададим конечный автомат, который имеет:

      • четыре состояния, S = {s0, s1, s2, s3} 
      • два входных сигнала X = {x0, x1}, где: x0 = 0, x1 = 1
      • шесть выходных сигналов Y = {y0, y1, y2, y3, y4, y5} где: y0 = 1, y1 = 2, y2 = 3, y3 = 4, y4 = 5, y5 = 6.

      Теперь представим автомат в виде графа:

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

      Функция переходов δ (sn, xn) определяется так: δ (s0, 0) = s1; δ (s2, 1) = s0; ….

      δ

      0

      1

      s0

      s1

      s3

      s1

      s2

      s0

      s2

      s2

      s0

      s3

      s1

      s3

       

      Таблица 1.

      Таблица 2 - определяет функцию выходов λ (sn, xn) так: λ (s0, 0) = y2; λ (s2, 1) = y3; ….

      λ

      0

      1

      s0

      y2

      y4

      s1

      y1

      y3

      s2

      y0

      y3

      s3

      y2

      y5

       

      Таблица 2.

      Реализация конечного автомата Мили

      Для программной реализации будет использоваться язык C# и технология WWF – как инструменты, упрощающие реализацию программных конечных автоматов. На рисунке 1, представлена блок-схема (WWF) программы, реализующей поведение автомата. 

      Нетрудно увидеть, что топология блок-схемы программы повторяет топологию графа переходов конечного автомата. С каждым состоянием связана операция, выполняющая функцию ожидания очередного события прихода нового входного сигнала и чтение его в стандартный буфер – int x, а также последующий анализ того, какой это сигнал. В зависимости от того, какой сигнал пришел на вход, выполняется та или иная функция y0y5 и происходит переход к новому состоянию. Построив программу подобную этой и добавив активные устройства, реализующие отдельные входные и выходные операции, можно управление каким-либо процессом поручить компьютеру.

      См. пример к главе: \020_State\002_MealyStateMachine

      Конечный автомат Мура

      Рассмотрим еще один тип конечно-автоматного преобразователя информации: Автомат Мура. Автоматы Мура образуют другой класс моделей, с точки зрения вычислительной мощности полностью эквивалентных классу автоматов Мили. В автомате Мура: A = <S, X, Y, s0, δ, λ>, выходная функция λ определяется не на паре <состояние, входной сигнал>, а только на состоянии . Выход автомата Мура определяется однозначно тем состоянием, в которое автомат переходит после приема входного сигнала.  

      ПРИМЕР:

      Зададим конечный автомат Мура, который будет являться эквивалентным автомату Мили, рассмотренному выше. Не составит труда преобразовать исходный автомат Мили в автомат Мура.  На графе автомата Мили легко прослеживается взаимосвязь элементов входного и выходного алфавитов. 

      Построив таблицу соответствий состояний автомата Мили алфавитным парам, легко увидеть какие состояния требуют расщепления.

       

       

      x0

      x1

      Расщепление состояния S

      s0

      y3

      y3

      Не требуется

      s1

      y2

      y2

      Не требуется

      s2

      y0

      y1

      s2 = {s2, s4}

      s3

      y4

      y5

      s3 = {s3, s5}

       

      Таблица 3.

       

      Состояния s2 и s3 автомата Мили расщепляются на два эквивалентных состояния: s2 = {s2, s4}, s3 = {s3, s5}, с каждым из которых связывается один выходной символ.

      Автомат Мура будет иметь:

      • шесть состояний, S = {s0, s1, s2, s3, s4, s5} 
      • два входных сигнала X = {x0, x1}, где: x0 = 0, x1 = 1.
      • шесть выходных сигналов Y = {y0, y1, y2, y3, y4, y5} где: y0 = 1, y1 = 2, y2 = 3, y3 = 4, y4 = 5, y5 = 6.

       

      Теперь представим автомат Мура в виде графа (в сравнении с автоматом Мили):

      Реализация конечного автомата Мура

      На рисунке 2, представлена блок-схема (WWF) программы реализующей поведение автомата Мура. 

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

      См. пример к главе: \020_State\003_MooreStateMachine

      Рассмотренные программные модели автоматов Мура и Мили - полностью эквивалентны.

      Структура паттерна на языке UML

      См. пример к главе: \020_State\001_State

      Структура паттерна на языке C#

      См. пример к главе: \020_State\001_State

      Участники

      • Context - Контекст:

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

      • State - Состояние:

      Задает интерфейс взаимодействия с «объектом-состоянием».

      • ConcreteState - Конкретное состояние:

      Реализует поведение (функции выхода и функции перехода) ассоциированное с определенным состоянием. Очевидно, что данный паттерн реализует модель КА – Мура.

      Отношения между участниками

      Отношения между классами

      • Конкретные классы (ConcreteStateA и ConcreteStateB) связанны связью отношения наследования с абстрактным классом State.
      • Конкретный класс Context связан связью отношения агрегации с абстрактным классом State.

      Отношения между объектами

      • Объект класса Context передает клиентские запросы объекту класса ConcreteState.
      • Объект класса Context может передать себя в качестве аргумента объекту типа State, который будет обрабатывать запрос. Такой подход позволит объекту-состоянию получить доступ к контексту и произвести замену состояния.
      • Объект класса Context обладает интерфейсом для конфигурирования его нужным состоянием. Один раз сконфигурировав контекст, клиенты должны отказаться от дальнейшей конфигурации. Чаще всего объекты ConcreteState сами принимают решение о том, при каких условиях и в каком порядке происходит изменение состояния.

      Мотивация

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

      Этот автомат имеет:

      • четыре состояния в которых может пребывать отец, S = { s0, s1, s2, s3 },  где:
      • s0 – Neutral (Нейтральное состояние)
      • s1 – Pity (Жалость)
      • s2 – Anger (Гнев)
      • s3 – Joy (Радость)
      • два входных сигнала – оценки полученные сыном в школе X = { x0, x1 }, где:
      • x0 = 2
      • x1 = 5
      • шесть выходных сигналов, т.е., действий отца  Y = { y0, y1, y2, y3, y4, y5 },  где:
        • y0 - брать ремень;
        • y1 - ругать сына;
        • y2 - успокаивать сына;
        • y3 - надеяться;
        • y4 - радоваться;
        • y5 - ликовать;

      Сына, получившего одну и туже оценку – ожидает дома совершенно различная реакция отца в зависимости от предыстории его учебы. Отец помнит, как его сын учился раньше и строит модель воспитания с учетом успехов и неудач сына. Например, после третьей двойки в истории (2, 2, 2) сына встретят ремнем (y0), а в истории (2, 2, 5, 2) – будут успокаивать(y2).

      Каждая предыстория определяет текущее состояние автомата, при этом некоторые входные предыстории эквивалентны (те истории которые приводят автомат в одно и тоже состояние), например, история (2, 2, 5) эквивалентна пустой истории, которой соответствует начальное состояние.

      Представим данный автомат таблично. Таблица 4 - определяет функцию переходов автомата из одного состояния в другое.

      Функция переходов δ (sn, xn) определяется так: δ (s0, 2) = s1; δ (s2, 5) = s0; ….

      δ

      2

      5

      s0 - Neutral

      s1

      s3

      s1 - Pity

      s2

      s0

      s2 - Anger

      s2

      s0

      s3 - Joy

      s1

      s3

      Таблица 4.

       

      Таблица 5 - определяет функцию выходов λ (sn, xn) так: λ (s0, 2) = y2; λ (s2, 5) = y3; ….

      λ

      2

      5

      s0 - Neutral

      y2 - успокаивать сына

      y4 - радоваться

      s1 - Pity

      y1 - ругать сына

      y3 - надеяться

      s2 - Anger

      y0 - брать ремень

      y3 - надеяться

      s3 - Joy

      y2 - успокаивать сына

      y5 - ликовать

      Таблица 5.

      Для упрощения программной реализации примера, рекомендуется преобразовать исходный автомат Мили в эквивалентный по вычислительной мощности автомат Мура. Для этого требуется произвести расщепление тех состояний - sn, которым соответствует более одной функции выхода - λ (sn, xn).

       

       

      x0

      x1

      Расщепление состояния S

      s0 - Neutral

      y3

      y3

      Не требуется

      s1 - Pity

      y2

      y2

      Не требуется

      s2 - Anger

      y0

      y1

      s2 = {s2, s4}

      s3 - Joy

      y4

      y5

      s3 = {s3, s5}

      Таблица 6.

      Из таблицы преобразования видно, что произошло формирование двух новых состояний: {s4, s5}. Ранее в состоянии гнева – s2, отец либо ругал сына – y1, либо использовал ремень – y0, а в состоянии радости – s3, либо просто радовался – y4, либо ликовал – y5. Таким образом, функциональность можно распределить по состояниям согласно соответствия силы эмоциональной экспрессии состояния и выполняемого действия.

      Например, s2-Гнев = {s2-Сильный Гнев, s4-Гнев}, s3-Радость = {s3-Радость, s5-Сильная Радость}. Соответственно: В состоянии «простого» гнева - s4-Гнев, можно ругать сына - y1 - ругать сына, а в состоянии сильного гнева - s2-Сильный Гнев, можно использовать ремень - y0 - брать ремень. В состоянии «простой» радости - s3-Радость, можно радоваться - y4 - радоваться, а в состоянии сильной радости - s5-Сильная Радость, можно ликовать - y5 - ликовать. Представим новый автомат таблично.

      Таблица 7 - определяет функцию переходов автомата из одного состояния в другое.

      δ

      2

      5

      s0 - Neutral

      s1

      s3

      s1 - Pity

      s4

      s0

      s2 - Strong Anger

      s2

      s0

      s3 - Joy

      s1

      s5

      s4 -  Anger

      s2

      s0

      s5Strong Joy

      s1

      s5

      Таблица 7. (Функции переходов - δ (sn, xn))

      Таблица 8 - определяет функцию выходов.

      λ

      2

      5

      s0 - Neutral

      y2 - успокаивать сына

      y4 - радоваться

      s1 - Pity

      y1 - ругать сына

      y3 - надеяться

      s2 - Strong Anger

      y0 - брать ремень

      y3 - надеяться

      s3 - Joy

      y2 - успокаивать сына

      y5 - ликовать

      s4 -  Anger

      y0 - брать ремень

      y3 - надеяться

      s5Strong Joy

      y2 - успокаивать сына

      y5 - ликовать

      Таблица 8. (Функции выходов - λ (sn, xn))

      Теперь представим автомат Мура в виде графа (в сравнении с автоматом Мили):

      Получившийся автомат Мура имеет:

      • шесть состояний в которых может пребывать отец, S = { s0, s1, s2, s3, s4, s5 },  где:
      • s0 – Neutral (Нейтральное состояние)
      • s1 – Pity (Жалость)
      • s2 – Strong Anger (Сильный Гнев)
      • s3 – Joy (Радость)
      • s4 – Anger (Гнев)
      • s5 – Strong Joy (Сильная Радость)
      • два входных сигнала – оценки полученные сыном в школе X = { x0, x1 }, где:
      • x0 = 2
      • x1 = 5
      • шесть выходных сигналов, т.е., действий отца  Y = { y0, y1, y2, y3, y4, y5 },  где:
        • y0 - брать ремень;
        • y1 - ругать сына;
        • y2 - успокаивать сына;
        • y3 - надеяться;
        • y4 - радоваться;
        • y5 - ликовать;

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

      Предлагается более подробно рассмотреть программную реализацию автомата Мура, имитирующего поведение умного отца. 

      Рассмотрим класс Father. Объект класса Father может находиться в одном из шести состояний: NeutralState (Нейтральное состояние), PityState (Жалость), JoyState (Радость), StrongJoyState (Сильная Радость), AngerState (Гнев), StrongAngerState (Сильный Гнев). Все классы состояний являются производными от базового абстрактного класса State. Объект типа Father хранит ссылку на определенный объект состояния.

      public class Father
          {
              internal State State { get; set; }
      
              public Father()
              {
                  State = new NeutralState();
              }
      
              public void FindOut(Mark mark)
              {
                  State.HandleMark(this, mark);
              }
          }
      

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

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

      internal abstract class State
          {
              internal virtual void HandleMark(Father father, Mark mark)
              {
                  ChangeState(father, mark);
              }
      
              protected abstract void ChangeState(Father father, Mark mark);
          }
      

      В подклассах класса State реализовано поведение, характерное для каждого конкретного состояния.

      // Нейтральное состояние (S0)
          internal class NeutralState : State
          {
              internal NeutralState()
              {
                  Console.WriteLine("Отец в нейтральном состоянии:");
                  Hope();
              }
      
              protected override void ChangeState(Father father, Mark mark)
              {
                  switch (mark)
                  {
                      case Mark.Two:
                          {
                              father.State = new PityState(); // S1
                              break;
                          }
                      case Mark.Five:
                          {
                              father.State = new JoyState();  // S3
                              break;
                          }
                  }
              }
      
              private void Hope()  // y3
              {
                  Console.WriteLine("Надеется на хорошие оценки.");
              }
          }
      
          // Состояние жалости (S1)
          internal class PityState : State
          {
              internal PityState()
              {
                  Console.WriteLine("Отец в состоянии жалости:");
                  Calm();
              }
      
              protected override void ChangeState(Father father, Mark mark)
              {
                  switch (mark)
                  {
                      case Mark.Two:
                          {
                              father.State = new AngerState(); // S4
                              break;
                          }
                      case Mark.Five:
                          {
                              father.State = new NeutralState(); // S0
                              break;
                          }
                  }
              }
      
              private void Calm()  // y2
      
              {
                  Console.WriteLine("Успокаивает сына.");
              }
          }
      
          // Состояние сильного гнева (S2)
          internal class StrongAngerState : State
          {
              internal StrongAngerState()
              {
                  Console.WriteLine("Отец в состоянии сильного гнева:");
                  BeatBelt();
              }
      
              protected override void ChangeState(Father father, Mark mark)
              {
                  switch (mark)
                  {
                      case Mark.Two:
                          {
                              father.State = new StrongAngerState(); // S2
                              break;
                          }
                      case Mark.Five:
                          {
                              father.State = new NeutralState(); // S0
                              break;
                          }
                  }
              }
              
              private void BeatBelt()  // y0
              {
                  Console.WriteLine("Бьет сына ремнем.");
              }
          }
      
          // Состояние радости (S3)
          internal class JoyState : State
          {
              internal JoyState()
              {
                  Console.WriteLine("Отец в состоянии радости:");
                  Joy();
              }
      
              protected override void ChangeState(Father father, Mark mark)
              {
                  switch (mark)
                  {
                      case Mark.Two:
                          {
                              father.State = new PityState(); // S1
                              break;
                          }
      
                      case Mark.Five:
                          {
                              father.State = new StrongJoyState(); // S5
                              break;
                          }
                  }
              }
              
              private void Joy()  // y4
              {
                  Console.WriteLine("Радуется успехам сына.");
              }
          }
      
          // Состояние гнева (S4)
          internal class AngerState : State
          {
              internal AngerState()
              {
                  Console.WriteLine("Отец в состоянии гнева:");
                  Scold();
              }
      
              protected override void ChangeState(Father father, Mark mark)
              {
                  switch (mark)
                  {
                      case Mark.Two:
                          {
                              father.State = new StrongAngerState(); // S2
                              break;
                          }
                      case Mark.Five:
                          {
                              father.State = new NeutralState(); // S0
                              break;
                          }
                  }
              }
              
              private void Scold()  // y1
              {
                  Console.WriteLine("Ругает сына.");
              }
          }
      
          // Состояние сильной радости (S5)
          internal class StrongJoyState : State
          {
              internal StrongJoyState()
              {
                  Console.WriteLine("Отец в состоянии сильной радости:");
                  Exult();
              }
      
      
      
      
      
              protected override void ChangeState(Father father, Mark mark)
              {
                  switch (mark)
                  {
                      case Mark.Two:
                          {
                              father.State = new PityState(); // S1
                              break;
                          }
                      case Mark.Five:
                          {
                              father.State = new StrongJoyState(); // S5
                              break;
                          }
                  }
              }
              
              private void Exult()  // y5
              {
                  Console.WriteLine("Ликует и гордится сыном.");
              }
          }
      

      Применимость паттерна

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

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

      Результаты

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

      • Локализация поведения, зависящего от состояния.

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

      • Разделяемые объекты состояния.

      Разные контексты Context могут разделять один и тот же объект типа State.

      Пакеты подписки с доступом ко всем курсам и сервисам

      Пакеты подписки с доступом ко всем курсам и сервисам

      Стартовый
      • Все видеокурсы на 3 месяца
      • Тестирование по 10 курсам
      • Проверка 5 домашних заданий
      • Консультация с тренером 30 мин
      49.99 $
      25.00 $
      Подписка
      Базовый
      • Все видеокурсы на 6 месяцев
      • Тестирование по 16 курсам
      • Проверка 10 домашних заданий
      • Консультация с тренером 60 мин
      89.99 $
      45.00 $
      Подписка
      Премиум
      • Все видеокурсы на 12 месяцев
      • Тестирование по 24 курсам
      • Проверка 20 домашних заданий
      • Консультация с тренером 120 мин
      169.99 $
      85.00 $
      Подписка
      комментарии и обсуждения
      Notification success
      Мы используем cookie-файлы, чтобы сделать взаимодействие с нашими веб-сайтами и услугами простым и значимым.