Каждое видео автора смотрю с широко раскрытыми глазами и ушами 😁 В плане объяснения архитектурных приемов автор - просто лучший! Нигде не видел, чтобы кто-то мог объяснять подобные темы настолько просто и наглядно. Я уже не один раз применял знания, полученные с этого канала, в своих проектиках 👍 Моё огромное спасибо автору, не был бы я нищебродом - обязательно бы задонатил.
Очень доходчиво объясняете, спасибо. Про паттерны у вас лучшее объяснение, надеюсь данная тема будет у вас продолжаться, хотелось бы про структурные паттерны. Желаю успехов каналу! p.s. Надеюсь с тапком все ок))
Стейт машина, по моему скромному, должна учится применяться начинающим джунам как можно скорее, потому что меня удивляет, как человек годами может решать задачи путём создания 5 булок, вместо лаконичного и давно известного решения По различиям стратегии и стейта, считаю что стейт подходит для описания поведения одной цельной и неразрывной сущности, а стратегия - для описания изменчивого аспекта какой-то сущности, или семейтсво алгоритмов Писал я как-то раз условный скролер, где использовал стейт машину для описания состояний оружия - стрельба, перезарядка, простой, заклинило и тп. А для реализации логики стрельбы использовал стретегию. Соответственно при подборе какого бонуса, допустим тройного выстрела, я просто менял реализации стрельбы с одной на другую прям на ходу. Вышло довольно занятно Ну и как всегда спасибо за контент!
Спасибо за видео, увидел немного другую реализацию этого патерна (я делал переключение не энамах, а на словаре с типами). Постоянно юзаю этот паттерн в самой основе архитектуры игры (BootstrapState, LocationLoadState, ActiveGameState, PauseState итд). В любом случае спасибо, автор молодец!
@@sergeykazantsev1655 K-syndicate. Чуваки сформулировали архитектуру и создали свой DI. Работяги при переписывании архитектуры на Zenject сталкиваются с циклическими зависимостями. Да и я сам так делал... и на VContainer пытался их машину написать...
Классный ролик как всегда. Но есть несколько вопросов =) : 1. Зачем вообще разные методы, если у нас будет расширяться функционал, то мы будем вносить изменения в каждый класс, что нарушает OCP??? Ведь в состояние можно зайти и выйти + постоянное обновление состояния. Следовательно всего 3 метода в базовом классе (Enter, Exit, Tick(float delta)). Если ещё дженериковые стейты сделать, то вообще будет песня, типа State. И добавить класс FSM у которого есть словарь Dictionary , текущее состояние , сетер стейта, методы добавления/ получения текущего и обновление текущего стейта. Если не брать в расчёт первый вопрос и продолжить смотреть текущий вариант, то другой вопрос. 2. Почему все абстрактные методы? ведь это обязывает реализовать метод, а как видели в видео там есть состояния у которых нет реализации, возможно стоит делать виртуальными чтобы не засорять класс-наследник?
1. С моей точки зрения, OCP не запрещает нам вносить изменения в класс. OCP запрещает нам изменять старую логику при модификации, а новая логика в существующем классе - это не изменение а то самое расширение. Если понимать OCP дословно, то тогда на каждый чих нужно будет наследоваться от написанного класса и это будет очень больно и трудно 2. Потому что по хорошему надо так организовать абстракцию чтобы любое состояние как-то выполняло тот или иной метод, и не было пустых. Туда например можно воткнуть Error-ы и информацию о том что починить активную башню невозможно. В конкретном примере да, можно сказать что нарушается LSP и ISP, но виртуальные методы мне кажется всё же мешают ясности и пониманию как то или иное состояние реагирует на тот или иной метод
@@sergeykazantsev1655 1. По текущему примеру. Нужно добавить Поиск врага/ в процессе строительства/починки/ атака врага / оборона - всё это придётся вносить в каждый стейт, а оно нужно ли каждому стейту? А есть уже 20 состояний, придёт ГД и такой давай сделаем чтобы башня при здоровье меньше 10 % усиливала дамаг и издавала спасательные звуки и придётся в 21 классе что-то писать, вместо того чтобы создать 1 класс нового состояния и когда здоровье меньше 10% просто сказать эй башня го в состояние такое-то = ) 2. При абстрактном классе с пустым виртуальным методом ничего не сломается при вызове метода базового класса, следовательно если в наследнике будет или нет конкретная реализация то она корректно отработает в любом случае. Лучше в абстрактном классе оставить пустой виртуальный метод, чем прописывать эесепшены или возвращать null/default в каждом наследнике.
1. Поиск врага не требует, чтобы его по разному реализовали разные состояния, я бы для поиска и стрельбы либо сделал бы флаг CanAttack либо вообще стрелял только если бы state = active То же самое касается усиленного урона, поведение урона башни не зависит от состояния, он зависит от хп, потому той проблемы что вы написали не будет)
2. С вашими аргументами согласен, но как и писал ранее, в идеале абстракция должна быть такой чтобы ни виртуальных методов, ни return null ни эксепшнов не было) но это в идеале
Скорее LSP. Можнл в качестве альтернативы передавать кнопки по другому, чтобы каждый state вместо обработки методов возвращал список доступных кнопок, но если в них будет уникальная логика, в зависимости от стейта , такое не получится
А почему нельзя то, что реализовано в отдельных классах, запихать в методы и переключать их присваивая делегату определенный метод? Тогда прийдется дописывать еще методы для перехода состояний, получается у состояния есть дополнительно логика для его включения и выключения?
Ну там может быть слишком много логики, чтобы в методы запихивать. В той же игре про шаурму - представьте ход врага и игрока в методы запихивать - повеситься можно)
@@sergeykazantsev1655 По назначению, конечно, абсолютно разные) Но, с точки зрения структуры очень даже похожи. За каждое состояние отвечает отдельный класс, также и для каждой команды выделяется собственный класс В классе контекста переключатель состояния выглядит вроде "SetState(new Idle(args))", и аналогично команда выглядит "Send(new InitCommand(args))".
Я установил несколько плагинов для более удобной разработки. Ничего волшебного и сверх крутого - просто автоподставка текста, цветовая тема из райдера, хоткеи из Visual Studio. Если интересно - можете написать мне в тг, я скину вам профиль в VS Code, если вы его загрузите у вас будет то же самое)
@@sergeykazantsev1655 Почему вы перешли на VSCode с Райдера (просто всегда видел, как наоборот, на Райдер перехдят). И как VSCode в плане удобства в сравнении с ним?
Спасибо за работу. Доставляет. Вопрос более общего плана. Как научиться уметь в архитектуру? Просто есть уровень условного Brackeys, когда главное заставить чтоб оно заработало, и пофиг что там внутри. И есть уровень когда все уже трут за чистую архитектуру, шаблон инжект и прочий космос. Может кто подскажет дорогу, как попасть на второй уровень? Отдельно по запчастям слушаешь, смотришь -все понятно. А откроешь любой проект с гитхаба с примером игрушки построеной по шаблонам, архитектуре и т.д. - и капец. Куда смотреть, как понимать, что за кого отвечает и зачем вообще нужно? Непонятно, одним словом
По архитектуре мое мнение что все упирается в опыт, и чтобы уметь в архитектуру, либо тебе этот опыт кто-то должен передать (лид, ментор) который будет смотреть ваш код, бить по рукам, и объяснять почему так, либо этот опыт надо получить самому. Во втором случае вы пишете игру и в какой то момент понимаете что дальше расширять игру очень сложно и неудобно. В этот момент вы пытаетесь понять почему это произошло, возвращаетесь к теории и понимаете о чем писалось в книжках и про что эти ваши паттерны и SOLID. К счастью или сожалению, архитектуры не стандартизированы, потому тут нет четких шаблонов как в тех же паттернах, все пишут что-то свое но делиться не спешат ибо часто это корпоративная тайна) я так думаю, мне так кажется
Спасибо за ответ А случаем нет волшебного пенделя в виде книги, тутора(eng, ru) с более широким пояснением на конкретной задаче, игре. Почему тут так, а туда лучше пока совсем не надо и т.д. И по типу, чтоб начать - пойдем отсюда, потому что... Я то понимаю, что пендель на самом деле = практика своей головой и руками. Но может есть хоть путеводная тропа))
К сожалению, я не смотрел современные курсы по юнити потому не знаю, как там обстоят дела Есть тг канал по архитектуре в юнити, может обсуждения или прикрепленные ресурсы вам помогут t.me/unity_architecture
Не состояние в словаре, а пул всех созданных состояний. Условно если у нас 5 состояний и если мы между ними переключаемся, лучше их сохранить в коллекции, а не пересоздавать заново каждый раз.
Каждое видео автора смотрю с широко раскрытыми глазами и ушами 😁 В плане объяснения архитектурных приемов автор - просто лучший! Нигде не видел, чтобы кто-то мог объяснять подобные темы настолько просто и наглядно. Я уже не один раз применял знания, полученные с этого канала, в своих проектиках 👍 Моё огромное спасибо автору, не был бы я нищебродом - обязательно бы задонатил.
Очень доходчиво объясняете, спасибо.
Про паттерны у вас лучшее объяснение, надеюсь данная тема будет у вас продолжаться, хотелось бы про структурные паттерны.
Желаю успехов каналу!
p.s. Надеюсь с тапком все ок))
Спасибо за тёплые слова) Тапок в порядке :D
Стейт машина, по моему скромному, должна учится применяться начинающим джунам как можно скорее, потому что меня удивляет, как человек годами может решать задачи путём создания 5 булок, вместо лаконичного и давно известного решения
По различиям стратегии и стейта, считаю что стейт подходит для описания поведения одной цельной и неразрывной сущности, а стратегия - для описания изменчивого аспекта какой-то сущности, или семейтсво алгоритмов
Писал я как-то раз условный скролер, где использовал стейт машину для описания состояний оружия - стрельба, перезарядка, простой, заклинило и тп.
А для реализации логики стрельбы использовал стретегию. Соответственно при подборе какого бонуса, допустим тройного выстрела, я просто менял реализации стрельбы с одной на другую прям на ходу. Вышло довольно занятно
Ну и как всегда спасибо за контент!
и шо много заработал?
Спасибо за видео, увидел немного другую реализацию этого патерна (я делал переключение не энамах, а на словаре с типами). Постоянно юзаю этот паттерн в самой основе архитектуры игры (BootstrapState, LocationLoadState, ActiveGameState, PauseState итд). В любом случае спасибо, автор молодец!
+REP за сравнения State и Strategy. На собесах спрашиваюь (мидл). От себя добавлю: не использовать синдикатовскую машину - циклическая зависимость.
А что такое синдикатовская машина? Оо
@@sergeykazantsev1655 K-syndicate. Чуваки сформулировали архитектуру и создали свой DI. Работяги при переписывании архитектуры на Zenject сталкиваются с циклическими зависимостями. Да и я сам так делал... и на VContainer пытался их машину написать...
@@sergeykazantsev1655 Думаю он про K-Syndicate
Понятно, надо будет посмотреть чего они там наворотили)
Спасибо, за твои уроки, очень понятно и интересно.
Спасибо большое за лаконичное объяснение паттерна, очень полезно! На смузи закинул)
Душевно благодарю) получил)
Молодец!! Самое лучшее объяснение паттерна state на ютубе
Спасибо! Коммент для продвижения)
Не посмотрел, но видос крутой
а как ты это понял? :D
Классный ролик как всегда.
Но есть несколько вопросов =) :
1. Зачем вообще разные методы, если у нас будет расширяться функционал, то мы будем вносить изменения в каждый класс, что нарушает OCP??? Ведь в состояние можно зайти и выйти + постоянное обновление состояния. Следовательно всего 3 метода в базовом классе (Enter, Exit, Tick(float delta)). Если ещё дженериковые стейты сделать, то вообще будет песня, типа State. И добавить класс FSM у которого есть словарь Dictionary , текущее состояние , сетер стейта, методы добавления/ получения текущего и обновление текущего стейта.
Если не брать в расчёт первый вопрос и продолжить смотреть текущий вариант, то другой вопрос.
2. Почему все абстрактные методы? ведь это обязывает реализовать метод, а как видели в видео там есть состояния у которых нет реализации, возможно стоит делать виртуальными чтобы не засорять класс-наследник?
1. С моей точки зрения, OCP не запрещает нам вносить изменения в класс. OCP запрещает нам изменять старую логику при модификации, а новая логика в существующем классе - это не изменение а то самое расширение. Если понимать OCP дословно, то тогда на каждый чих нужно будет наследоваться от написанного класса и это будет очень больно и трудно
2. Потому что по хорошему надо так организовать абстракцию чтобы любое состояние как-то выполняло тот или иной метод, и не было пустых. Туда например можно воткнуть Error-ы и информацию о том что починить активную башню невозможно. В конкретном примере да, можно сказать что нарушается LSP и ISP, но виртуальные методы мне кажется всё же мешают ясности и пониманию как то или иное состояние реагирует на тот или иной метод
@@sergeykazantsev1655 1. По текущему примеру.
Нужно добавить Поиск врага/ в процессе строительства/починки/ атака врага / оборона - всё это придётся вносить в каждый стейт, а оно нужно ли каждому стейту?
А есть уже 20 состояний, придёт ГД и такой давай сделаем чтобы башня при здоровье меньше 10 % усиливала дамаг и издавала спасательные звуки и придётся в 21 классе что-то писать, вместо того чтобы создать 1 класс нового состояния и когда здоровье меньше 10% просто сказать эй башня го в состояние такое-то = )
2. При абстрактном классе с пустым виртуальным методом ничего не сломается при вызове метода базового класса, следовательно если в наследнике будет или нет конкретная реализация то она корректно отработает в любом случае. Лучше в абстрактном классе оставить пустой виртуальный метод, чем прописывать эесепшены или возвращать null/default в каждом наследнике.
1. Поиск врага не требует, чтобы его по разному реализовали разные состояния, я бы для поиска и стрельбы либо сделал бы флаг CanAttack либо вообще стрелял только если бы state = active
То же самое касается усиленного урона, поведение урона башни не зависит от состояния, он зависит от хп, потому той проблемы что вы написали не будет)
2. С вашими аргументами согласен, но как и писал ранее, в идеале абстракция должна быть такой чтобы ни виртуальных методов, ни return null ни эксепшнов не было) но это в идеале
@@sergeykazantsev1655 это геймдев, идеальных проектировок не будет =) постоянно что-то меняется
Автора рекомендую, приятно посмотреть.
TowerState больше ISP или LSP нарушает? Раздутая абстракция, не реализуемые в наследниках методы интерфейса
Скорее LSP. Можнл в качестве альтернативы передавать кнопки по другому, чтобы каждый state вместо обработки методов возвращал список доступных кнопок, но если в них будет уникальная логика, в зависимости от стейта , такое не получится
Новое видео)
А почему нельзя то, что реализовано в отдельных классах, запихать в методы и переключать их присваивая делегату определенный метод? Тогда прийдется дописывать еще методы для перехода состояний, получается у состояния есть дополнительно логика для его включения и выключения?
Ну там может быть слишком много логики, чтобы в методы запихивать. В той же игре про шаурму - представьте ход врага и игрока в методы запихивать - повеситься можно)
Несколько раз пересмотрел и понял что я про стратегию подумал.
бывает)
Паттерн Состояние больше похож на паттерн Команда, чем на Стратегию, имхо)
А в чём, по вашему, схожесть команды и состояния?)
@@sergeykazantsev1655 По назначению, конечно, абсолютно разные) Но, с точки зрения структуры очень даже похожи.
За каждое состояние отвечает отдельный класс, также и для каждой команды выделяется собственный класс
В классе контекста переключатель состояния выглядит вроде "SetState(new Idle(args))", и аналогично команда выглядит "Send(new InitCommand(args))".
ну в этом да, полиморфизм во всей его красоте)
Cool)
А какую тему в VS Code используете? И может дадите какие-то советы/рекомендации по настройке VS Code для Unity?
Я установил несколько плагинов для более удобной разработки. Ничего волшебного и сверх крутого - просто автоподставка текста, цветовая тема из райдера, хоткеи из Visual Studio.
Если интересно - можете написать мне в тг, я скину вам профиль в VS Code, если вы его загрузите у вас будет то же самое)
@@sergeykazantsev1655 Почему вы перешли на VSCode с Райдера (просто всегда видел, как наоборот, на Райдер перехдят). И как VSCode в плане удобства в сравнении с ним?
Райдер лучше, но VS Code бесплатный :D
Спасибо за работу. Доставляет.
Вопрос более общего плана. Как научиться уметь в архитектуру?
Просто есть уровень условного Brackeys, когда главное заставить чтоб оно заработало, и пофиг что там внутри.
И есть уровень когда все уже трут за чистую архитектуру, шаблон инжект и прочий космос.
Может кто подскажет дорогу, как попасть на второй уровень? Отдельно по запчастям слушаешь, смотришь -все понятно. А откроешь любой проект с гитхаба с примером игрушки построеной по шаблонам, архитектуре и т.д. - и капец. Куда смотреть, как понимать, что за кого отвечает и зачем вообще нужно?
Непонятно, одним словом
По архитектуре мое мнение что все упирается в опыт, и чтобы уметь в архитектуру, либо тебе этот опыт кто-то должен передать (лид, ментор) который будет смотреть ваш код, бить по рукам, и объяснять почему так, либо этот опыт надо получить самому.
Во втором случае вы пишете игру и в какой то момент понимаете что дальше расширять игру очень сложно и неудобно. В этот момент вы пытаетесь понять почему это произошло, возвращаетесь к теории и понимаете о чем писалось в книжках и про что эти ваши паттерны и SOLID.
К счастью или сожалению, архитектуры не стандартизированы, потому тут нет четких шаблонов как в тех же паттернах, все пишут что-то свое но делиться не спешат ибо часто это корпоративная тайна) я так думаю, мне так кажется
Спасибо за ответ
А случаем нет волшебного пенделя в виде книги, тутора(eng, ru) с более широким пояснением на конкретной задаче, игре. Почему тут так, а туда лучше пока совсем не надо и т.д.
И по типу, чтоб начать - пойдем отсюда, потому что...
Я то понимаю, что пендель на самом деле = практика своей головой и руками.
Но может есть хоть путеводная тропа))
К сожалению, я не смотрел современные курсы по юнити потому не знаю, как там обстоят дела
Есть тг канал по архитектуре в юнити, может обсуждения или прикрепленные ресурсы вам помогут t.me/unity_architecture
Зачем хранить состояние в словаре? Почему не использовать статический класс? Синглтон это слишком)
Не состояние в словаре, а пул всех созданных состояний. Условно если у нас 5 состояний и если мы между ними переключаемся, лучше их сохранить в коллекции, а не пересоздавать заново каждый раз.
@@sergeykazantsev1655 А статика не пойдет - потому что экземпляров обьектов может быть много, и тогда все состояния будую для всез одинаковы, понял.