Паттерн Observer, С#, unity, gamedev,
Ойындар
Попробовал разжевать ключевые идеи и принципа паттерна Observer, а также показать его эволюцию.
Если будут вопросы
мой тг @wargy
моя почта kazancev.s215@gmail.com
Автору на кофе и шаурму
4276 5500 5792 8742 - карта Сбербанка
Тайминги:
00:00 Введение
01:00 Проблема уведомления классов
01:17 Конкретный пример: введение
02:13 Плохое решение №1: уведомляем классы через Update
03:04 Плохое решение №2: уведомляем через композицию
04:54 Паттерн Observer в картинках
06:16 Паттерн Observer в UML-схеме
07:19 Рефакторим наш Player под Observer
09:03 Рефакторим слушателей, HealthBar
10:03 UML-схема нашего кода
11:08 Observer в наши дни
13:15 Observer в других паттернах
14:40 Финал
Пікірлер: 33
Сергей, спасибо! Материал востребованный, подача безупречная! Скинул линк на ваш видос сокурсникам. Поржали с Лунтика. Хотел бы увидеть столь же усвояемый материал по DIP в реализации Zenject Ну и по остальным принципам SOLID в таком же стиле! Спасибо от сообщества!
@sergeykazantsev1655
Жыл бұрын
Спасибо, OCP уже выложил, DI тоже в планах)
@user-yn6np8xi7k
Жыл бұрын
По Zenject было бы интересно послушать. Но там отдельный плейлист нужен будет :)
Братан, хорош, давай, давай вперед! Контент в кайф, можно ещё? Вообще красавчик!
@sergeykazantsev1655
Жыл бұрын
О, ребятушки с ExtremeCode пожаловали) Спасибо за комменты)
Очень хорошо объясняете! Спасибо!
Очень круто объясняете. Приятно слушать и смотреть, спасибо!
Спасибо чел, я прям прозрел когда посмотрел твоё видео. У меня будето пазл в голове сложился. Спасибо!
Классно, понятно, интересно, виртуозно
тупа лайк под каждым видео, по твоим видосам можно и мидлом стать
Спасибо!
12:06 Нынче вроде можно ивенты проверять на нуль одной строкой, вот так: Event?.Invoke()
Повторение, мать учения!
Ничего не понятно, но подписалась))
Здравствуйте. Хотел задать вопрос. Насколько я понимаю функционал паттерна Observer как и использование событий в данном случае, можно заменить на реактивные свойства, которые реализованы в том же UniRx. Хотел спросить все ли правильно я понимаю.
@sergeykazantsev1655
Жыл бұрын
Да, всё верно. UniRx это продолжение развития паттерна Observer. Там так же есть подписки, отписки, уведомления и реакции на уведомления, только они имеют более удобный вид. UniRx как я понимаю вообще на этом выстроил свою философию кода, со своим IObservable и подписками на потоки данных
@Guy-qv8bq
Жыл бұрын
@@sergeykazantsev1655 Спасибо за ответ. Вы делаете очень крутой обучающий контент. Буду с нетерпением ждать от вас новых видео)
Мощно💪
Кстати, очень бы не помешали примеры по разным паттернам, но не в ООП, а в Дата-ориентированном программировании в Юнити. Не планируется ли случайно такого в ближайшее время?
@sergeykazantsev1655
11 ай бұрын
Планируется, но не в ближайшее время)
получается современная версия паттерна это просто action в классе object и подписка/отписка нужного метода от него в классе observer? никих интерфейсов, ничего. правильно?
@sergeykazantsev1655
Жыл бұрын
если я Вас правильно понимаю, то скорее всего да. В подписке и отписке на экшны интерфейс не нужен. Но тут очень важно понимать, что если Вы на собесе скажете, что паттерн Observer это просто action в классе Object, и там подписка и отписка нужного метода без интерфейсов - я думаю, собеседующий этот ответ не одобрит. Тут в Observer важен сам принцип - взаимодействия между классами через события. Реализуете ли вы его классически или через action-ы - это уже вторично)
@vlpalamar8639
Жыл бұрын
@@sergeykazantsev1655 благодарю за ответ)
8:54 Интерфейс, как и абстрактный класс, позволяет использовать protected.
@sergeykazantsev1655
4 ай бұрын
Это очень здорово, но здесь то это к чему?
@ichbinschlange
4 ай бұрын
@@sergeykazantsev1655, к "в интерфейсе приватные поля не создашь". private не создашь, protected создашь, что в сущности тоже самое.
Тут единственный вопрос в конце к методу UpdateUI у HealthBar. А не лучше его сделать приватным, чтобы только сам класс решал, когда и как он будет обновлять полоску здоровья? А то вдруг злой геймменеджер снаружи его ради прикола будет вызывать? Или есть какой-то смысл его оставить публичным?
@sergeykazantsev1655
3 ай бұрын
на 9:07 я как раз сделал UpdateUI приватным, насколько я помню, разве нет?) Или вопрос про HealthChanged?
Сегодня бежал с работы домой, не успел добежать и на пол пути реализовал интерфейс АйОбсёрвер. Inventory.attire.pants.SetDirty() Шютка))
@sergeykazantsev1655
11 ай бұрын
Да, главное аккуратнее работать с классом VokzalnayaShaurma, он прям мотивирует подобный интерфейс реализовать)
@COOKIEMONSTER90
11 ай бұрын
@@sergeykazantsev1655 =)
Есть более удобный способ использования Наблюдателя без интерфейсов. - Создаём класс события, являющимся ScriptableObject. - Примерная реализация: [CreateAssetMenu] public class GameEvent : ScriptableObject { private List _listeners = new List(); public void Subscribe(Action newListener) { if (_listeners.Contains(newListener)) { Debug.LogError($"Попытка повторного добавления {newListener} в список подписчиков события {name}."); return; } _listeners.Add(newListener); } public void Unsubscribe(Action listener) { if (!_listeners.Contains(listener)) { Debug.LogError($"Попытка удалить несуществующего подписчика {listener} из списка подписчиков события {name}."); return; } _listeners.Remove(listener); } public void Publish() { if (_listeners.Count == 0) { Debug.LogError($"Попытка инициировать событие {name}, у которого нет подписчиков"); return; } for (int i = 0; i _listeners[i].Invoke(); } } - Для каждого события создаём отдельный экземпляр с уникальным именем в ассетах. - Ссылки на конкретный экземпляр должны быть у издателя и подписчика(ов). - Издатель просто вызывает Publish() когда нужно. Подписчик просто передаёт метод в Subscribe([имя метода]), который должен обрабатывать событие. - Для событий с аргументами можно расширить класс GameEvent. Это позволяет подписчикам знать только о событиях, игнорируя подробности о субъектах. Самому событию без разницы кто его публикует и обрабатывает.
@sergeykazantsev1655
11 ай бұрын
Ну это сигнальная шина некая получается, у меня по EventBus даже видео на канале есть)