Комментарии 5
Зачем писать эти уродливые анонимные методы?
Зачем создавать контейнер для делегата?
Зачем создавать контейнер для делегата?
+3
Команда оформляется через интерфейс. Выражать стратегии очень удобно через анонимные методы, но когда они состоят из одного метода и ситуативны. В данном случае автор зачем-то выделил разделил логику команды и её имя. Из-за чего система стала менее очевидной (команда с одним именем и типом имеет разные действия).
Выражается это вот так
В коде автора статьи мы имеем связь Has-a, у него есть сущность «команда бота» которая содержит непосредственно действие и название. Я не вижу предпосылок для этого, как по мне логичней будет связь is-a. Команда движение есть команда бота и содержит направление движения. Ну а команда бота в свою очередь реализуют интерфейс ICommand (можно обойтись и без него).
Какие недостатки у has-a в статье:
1) Пришлось выделить фабричные методы для создания команд движения которые дублируют друг друга.
2) Redo не показана в статье но там те же пляски с дубляжом будут.
В данном случае в целом классическая дилемма: композиция против наследования. Обычно совет звучит о предпочтение композиции наследованию, но в данном случае избавления от наследования сделало систему менее стойкой и однородной.
Насчёт уродливых анонимных методов
Это просто рудемент. Вместо
new delegate(Bot bot) { /*code*/ }
Сейчас пишут
(bot) => //code
Выражается это вот так
public interface ICommand
{
void Execute();
void Redo();
}
В коде автора статьи мы имеем связь Has-a, у него есть сущность «команда бота» которая содержит непосредственно действие и название. Я не вижу предпосылок для этого, как по мне логичней будет связь is-a. Команда движение есть команда бота и содержит направление движения. Ну а команда бота в свою очередь реализуют интерфейс ICommand (можно обойтись и без него).
Какие недостатки у has-a в статье:
1) Пришлось выделить фабричные методы для создания команд движения которые дублируют друг друга.
2) Redo не показана в статье но там те же пляски с дубляжом будут.
В данном случае в целом классическая дилемма: композиция против наследования. Обычно совет звучит о предпочтение композиции наследованию, но в данном случае избавления от наследования сделало систему менее стойкой и однородной.
Насчёт уродливых анонимных методов
Это просто рудемент. Вместо
new delegate(Bot bot) { /*code*/ }
Сейчас пишут
(bot) => //code
+3
romaan27 Спасибо большое за подробное объяснение. У меня к вам возник вопрос — может у вас есть красивое решение через паттерны или дженерики.
В данный момент бьюсь с собственной (пока не нашел готового решения) системой игровых событий, которая представляет из себя 'шину' EventBus, у которой есть очередь, в которую кладутся объекты, реализующие интерфейс IGameEvent, у которого есть всего пара методов вида getMessage, возвращающий строку и getHappened, возвращающий время создания события. Таймер в EventBus каждую секунду проверяет очередь и pop-ает оттуда события. При извлечении события используется шаблон Observer — любой класс может подписаться на событие извлечения эвента и получить экземляр этого IGameEvent от EventBus.
Вопрос в следующем. Поверх IGameEvent есть разные интерфейсы, расширяющие его. Например, существует IDayTimeEvent, имеющий (момимо message и time) информацию вида «Наступил день/ночь...» или IPaydayEvent, имеющий информацию вида «Получено 200 монет на счет». Приводит все к тому, что каждый подписавшийся на EventBus class получает все IGameEvent-ы и если он ждет какой то конкретный тип информации (ему не важно время дня или монеты, а важна другая информация) — ему приходится явно приводить пришедшие объекты к конкретным интерфейсам, что рушит весь смысл интерфейсовости очереди EventBus. Как думаете — может перенести этот кастинг в EventBus, чтобы она имела возможность разделять события по куче других Bus-ов, которые будут эммитить конкретный интерфейс или же вообще отказаться от этой концепции?
В данный момент бьюсь с собственной (пока не нашел готового решения) системой игровых событий, которая представляет из себя 'шину' EventBus, у которой есть очередь, в которую кладутся объекты, реализующие интерфейс IGameEvent, у которого есть всего пара методов вида getMessage, возвращающий строку и getHappened, возвращающий время создания события. Таймер в EventBus каждую секунду проверяет очередь и pop-ает оттуда события. При извлечении события используется шаблон Observer — любой класс может подписаться на событие извлечения эвента и получить экземляр этого IGameEvent от EventBus.
Вопрос в следующем. Поверх IGameEvent есть разные интерфейсы, расширяющие его. Например, существует IDayTimeEvent, имеющий (момимо message и time) информацию вида «Наступил день/ночь...» или IPaydayEvent, имеющий информацию вида «Получено 200 монет на счет». Приводит все к тому, что каждый подписавшийся на EventBus class получает все IGameEvent-ы и если он ждет какой то конкретный тип информации (ему не важно время дня или монеты, а важна другая информация) — ему приходится явно приводить пришедшие объекты к конкретным интерфейсам, что рушит весь смысл интерфейсовости очереди EventBus. Как думаете — может перенести этот кастинг в EventBus, чтобы она имела возможность разделять события по куче других Bus-ов, которые будут эммитить конкретный интерфейс или же вообще отказаться от этой концепции?
0
Зарегистрируйтесь на Хабре , чтобы оставить комментарий
Реализация шаблона проектирования Command в Unity