:: Не фоксом единым
Паттерн State (Состояние)
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
На metanit.com описан паттерн State. Почитал статью, возникли вопросы.
Ratings: 0 negative/0 positive
Паттерн State (Состояние)
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Во первых, в статье даётся определение:

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

Конечно, это определение корректное, но - очень размытое, и не передающее сути. На мой взгляд, правильно будет:

Цитата:
State - это объектно-ориентированная реализация конечного автомата.



Исправлено 2 раз(а). Последнее : S-type, 08.06.18 15:19
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
S-type
Автор

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

Часть текста скрыта

interface IWaterState // интерфейс состояний
{
void Heat(Water water); // действие "нагреть"
void Frost(Water water); // действие "охладить"
}
class Water // Context
{
public IWaterState State { get; set; }
public Water(IWaterState ws) // начальное состояние
{
State = ws;
}
public void Heat() // действие "нагреть"
{
State.Heat(this);
}
public void Frost() // действие "охладить"
{
State.Frost(this);
}
}
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();
}
}
class Program
{
static void Main(string[] args)
{
Water water = new Water(new LiquidWaterState());
water.Heat(); // Превращаем жидкость в пар
water.Frost(); // Превращаем пар в жидкость
water.Frost(); // Превращаем жидкость в лед
water.Frost(); // Уже и так лёд
Console.ReadLine();
}
}




Жутко не нравится, что используется конструкция:

public void Frost(Water water) // действие "охладить"
{
Console.WriteLine("Превращаем пар в жидкость");
water.State = new LiquidWaterState();
}

Это ведь функция с побочным эффектом ru.wikipedia.org
На мой взгляд, подобного надо избегать.

Как можно изменить код, что бы не было функции с побочным эффектом?



Исправлено 3 раз(а). Последнее : S-type, 08.06.18 09:54
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
S-type
Во первых, в статье даётся определение:
IMHO оно более корректное и, главное, понятное, в отличие от твоего. Конечный автомат можно реализовать и безо всяких шаблонов state. Кроме того, к его определению можно свести вообще практически всё что угодно - любую программу на шарпе в частности.
S-type
Конечно, это определение корректное, но - очень размытое, и не передающее сути.
Наоборот - оно более "конкретное".
S-type
Жутко не нравится, что используется конструкция:
...
Это ведь функция с побочным эффектом
На мой взгляд, подобного надо избегать.
Во-первых для шаблона state не обязательно выполнение действия будет связано с изменением состояния. Ключевое в шаблоне то, что САМО действие зависит от состояния, а значит изменение состояния вызовет изменение действия.
Во-вторых ничего криминального в недетерминированных функциях и функциях с побочными эффектами нет. Я думаю что невозможно написать программу состоящую сплошь из "чистых" функций. Ну точнее написать то можно, но смысла в ней не будет. Создание нового файла, изменение записи и в БД и даже просто вывод текста на экран - это уже "побочный эффект функции".


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
S-type
Во первых, в статье даётся определение:
IMHO оно более корректное и, главное, понятное, в отличие от твоего. Конечный автомат можно реализовать и безо всяких шаблонов state. Кроме того, к его определению можно свести вообще практически всё что угодно - любую программу на шарпе в частности.
Под "конечный автомат" имеется ввиду не "любая программа на C#", а ДКА ru.wikipedia.org Так что, приведённое мной определение корректно с математической точки зрения. Опять таки, можно реализовать ДКА с помощью матрицы переходов, с помощью switch, и при этом обе программы будут попадать под определение

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

Но, при этом они не будут реализовывать паттерн State, потому что паттерн State - это именно "объектно-ориентированная реализация КА", когда каждое состояние описывается своим объектом.




Но, собственно, мой вопрос был о другом

Igor Korolyov
S-type
Жутко не нравится, что используется конструкция:
...
Это ведь функция с побочным эффектом
На мой взгляд, подобного надо избегать.
Во-первых для шаблона state не обязательно выполнение действия будет связано с изменением состояния. Ключевое в шаблоне то, что САМО действие зависит от состояния, а значит изменение состояния вызовет изменение действия.

Т.е. вот такая реализация:



Это то же реализация паттерна State?

Igor Korolyov
Во-вторых ничего криминального в недетерминированных функциях и функциях с побочными эффектами нет. Я думаю что невозможно написать программу состоящую сплошь из "чистых" функций. Ну точнее написать то можно, но смысла в ней не будет. Создание нового файла, изменение записи и в БД и даже просто вывод текста на экран - это уже "побочный эффект функции".

С этим, безусловно, полностью согласен. Вот только в примере с метанита функция "втихаря" меняет состояние объекта - что IMHO кране не правильно.
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Погуглил. cpp-reference.ru говорится:

Цитата:
Все полученные от клиента запросы класс Context (в примере с метанита это класс Water) просто делегирует объекту «текущее состояние», при этом в качестве дополнительного параметра передается адрес объекта Context.
Используя этот адрес, в случае необходимости методы класса State могут изменить «текущее состояние» класса Context.

Выходит, в данном случае функция с побочным эффектом обязательна.

Хотя, тут же написано:

Цитата:
Паттерн State не определяет, где именно определяется условие перехода в новое состояние. Существует два варианта: класс Context или подклассы State.

А в случае, если переходом в новое состояние "рулит" Context, то в классы StateN передавать ссылку на Context не нужно.

В общем, как то всё мутно



Исправлено 1 раз(а). Последнее : S-type, 08.06.18 20:34
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Ну этот объект и есть "состояние", так что абсолютно ничего страшного что состояние (автомата в целом) он же и меняет. Более того, это одно из отличий этого шаблона от strategy Т.е. он должен менять текущее состояние в основном объекте.
Впрочем, даже если бы он менял и другие поля - и в этом я не нахожу "крамолы". Этот шаблон есть декомпозиция сложной логики на простые части. Семантически state-классы являются частью своего владеющего объекта, т.е. они не имеют смысла в отрыве от него (в отличие от шаблона strategy). Они вполне могут быть реализована вложенными классами и тупо прописывать то что надо в приватные члены основного класса (если логика реализации отдельного шага требует такого "прописывания"). Они вообще не обязаны быть публичным - при том будут замечательно выполнять свою функцию, разделяя "километровый" монолитный код основных методов на множество маленьких "частичных" реализаций, и формализуя логику перехода из состояния в состояние.

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

S-type
Вот только в примере с метанита функция "втихаря" меняет состояние объекта - что IMHO кране не правильно.
В других примерах тоже - вообще это и есть суть шаблона - сделал дело и перевёл автомат в очередное состояние. А "перевод" это и есть присваивание нужного (обычно другого, т.к. чаще идёт переход на "другой" узел графа КА, а не итеративный возврат к тому же самому состоянию) State в свойство/поле основного класса.
Твой вариант как раз нарушает этот принцип. Т.к. получается что исполнение логики отдельного шага КА НЕ гарантирует смены состояния всего автомата, а это неправильно. На английской вики, или в других источниках можешь глянуть - вызов setState() (шарповское "присвоение свойству" это и есть вызов спецметода set_State) является непременным признаком этого шаблона.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Igor Korolyov
вообще это и есть суть шаблона
+100500
Практически OFF к данному топику, но...
Что такое паттерны, и для чего целую книгу написали.

Появляется некая задача. До кода еще далеко, нужно придумать алгоритм решения.
Вот тут они на помощь и приходят.

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

Вот когда приходишь к выводу, при проектировании, что стоит именно этот паттерн применить, можно нагуглить кучу его реализаций, на нужном, или похожих языках


------------------
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
По поводу дефиниции ... - ну с этим можно согласится.
Рад, что мы достигли консенсуса.

Igor Korolyov
Твой вариант как раз нарушает этот принцип. Т.к. получается что исполнение логики отдельного шага КА НЕ гарантирует смены состояния всего автомата, а это неправильно.
Спасибо, теперь понятно.
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Аспид
Да и сами паттерны))) Часто в коде превращаются в жуткую смесь, медиатора и стэйта)))
В общем то, при теоретическом изучении, наверное стоит всего лишь запомнить, отложить в глубине памяти, что есть решение подобных алгоритмов

Вот когда приходишь к выводу, при проектировании, что стоит именно этот паттерн применить, можно нагуглить кучу его реализаций, на нужном, или похожих языках

Вопрос - какие реально (на практике) паттерны применяете?
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
"На практике" паттерны применяют даже те, кто про них и слыхом не слыхивал Правда при этом они обычно "изобретают велосипед", и зачастую с квадратными колёсами (поскольку не учитывают какой-нить нюанс, который уже многократно был "обмусолен" при различных реализациях того или иного шаблона). Многие шаблоны "встроены" в языки программирования или системное АПИ - event как самый классический пример.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
S-type
Вопрос - какие реально (на практике) паттерны применяете?
Ну так сходу точно. Репозиторий, MVC, Singlton
О State ... не часто встречается, и в смеси с медиатором)))
Igor Korolyov
"На практике" паттерны применяют даже те, кто про них и слыхом не слыхивал
Прямо лучше не скажешь!)

Просто смотришь на какую то хрень, и вдруг думаешь, так это же ОН!)
И сразу становится яснее реализация. По крайней мере, к своим знаниям, сразу добавляешь кучу чужих.


------------------




Исправлено 1 раз(а). Последнее : Аспид, 09.06.18 15:01
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
S-type
Автор

Сообщений: 2969
Дата регистрации: 24.04.2004
Igor Korolyov
"На практике" паттерны применяют даже те, кто про них и слыхом не слыхивал
Есть такой анекдот.

Приходят однажды журналисты к Альберту Эйнштейну (в некоторых версиях - к Нильсу Бору) взять у него интервью.
Смотрят - а у него над дверью висит подкова.
Они ему:
- Вы верите в эти суеверия?
Эйнштейн:
- Мне сказали, что подкова помогает даже тем, кто в неё не верит...

Igor Korolyov
Многие шаблоны "встроены" в языки программирования или системное АПИ - event как самый классический пример.

Сюда можно добавить: DbContext - это реализация паттерна "Unit Of Work", DbSet<T> - реализация паттерна "репозиторий". Или, если создать программу Core MVC, то можно увидеть что то вроде:

var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.UseApplicationInsights()
.Build();

Это использование паттерна Method chainig (цепочка методов).
Ratings: 0 negative/0 positive
Re: Паттерн State (Состояние)
Аспид

Сообщений: 3475
Откуда: Москва
Дата регистрации: 01.04.2005
Когда начинают учить на музыкальных инструментах, очень много внимания, уделяют апплекатуре. (Правильной расстановке пальцев)
Умеющий играть, практически не думает об этом. Он только в сложных местах, задумывается как сподручнее) Я не говорю об Ойстрахе или Рахманинове))) Те видимо всегда на автомате)))

Так и тут, привыкаешь к чему то, и не думаешь об этом.
Но случаются, необычные сложные моменты, тут и думаешь... куда пальчик поставить)


------------------
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 2 (Гостей: 2)

© 2000-2024 Fox Club 
Яндекс.Метрика