Паттерны программирования игр
— Другой взгляд на паттерны проектирования
77
классами. Но большинство программистов сейчас пред-
почитают функциональное программирование как бо-
лее комфортную парадигму для себя. Необходимость
создания целого интерфейса только для того, чтобы про-
сто получить уведомление, не соответствует сегодня-
шней эстетике.
Это кажется тяжелым и громоздким. Это и
есть
тяже-
ло и громоздко. Например, вы не можете использовать
единственный класс, который применяет разные мето-
ды уведомления для разных субъектов.
Более современный подход заключается в том, чтобы
«наблюдатель» был только ссылкой на метод или функ-
цию. На языках с функциями первого класса, и особен-
но с замыканиями, это гораздо более распространенный
способ создания наблюдателей.
Например, C# имеет «события», определенные в язы-
ке. То есть наблюдатель — это «делегат», что является
термином, обозначающим ссылку на метод. В систе-
ме событий JavaScript наблюдатели
могут
быть объ-
ектами, поддерживающими специальный протокол
EventListener
, но они также могут быть просто функ-
циями. Почти всегда используется последнее.
Разрабатывай я систему наблюдателей сегодня,
я взял бы за основу функциональный стиль, а не клас-
сы. Даже в C++ я стремился бы к системе, позволяю-
щей регистрировать указатели на функции в качестве
наблюдателей, а не экземпляры некоторого интерфей-
са
Observer
.
Наблюдатели завтра
В наши дни системы событий и другие похожие на на-
блюдателя паттерны невероятно распространены.
Они — проторенная дорожка. Но когда вы становитесь
автором нескольких больших приложений, при исполь-
зовании их вы начинаете замечать интересную законо-
мерность. Большая часть кода в ваших наблюдателях
выглядит одинаково. Обычно это что-то вроде:
Вот почему субъект
обычно передает себя
наблюдателю. По-
скольку у наблюдателя
только один метод
onNotify()
, если он
наблюдает за несколь-
кими субъектами, ему
нужна возможность
определить, кто его вы-
звал.
В наши дни практически
каждый
язык имеет за-
мыкания. В C++ эту про-
блему решили путем
внедрения замыканий
без сборщиков мусора,
и даже Java наконец на-
чала действовать
и представила замыка-
ния в JDK 8.
1.
Получить уведомление об изменении состояния.
2.
Императивно изменить некоторый фрагмент
пользовательского интерфейса, чтобы отразить
новое состояние.
«О, здоровье героя сейчас 7? Позвольте мне установить
ширину панели здоровья в 70 пикселей». Через некото-
рое время это становится довольно утомительным. Спе-
циалисты в области информационных технологий и раз-
работчики программного обеспечения
давно
пытаются
устранить подобное однообразие. Их попытки извест-
ны под именами: «программирование потоков данных»,
«функциональное реактивное программирование» и т. д.
Несмотря на некоторые успехи, обычно в ограничен-
ных областях, таких как обработка звука или разработ-
ка чипов, Святой Грааль до сих пор не найден. Между
тем, менее амбициозный подход начал набирать силу.
Во многих современных прикладных средах теперь ис-
пользуется «привязка данных».
В отличие от более радикальных моделей, привязка
данных не пытается полностью исключить императив-
ный код и не пытается построить все ваше приложение
вокруг гигантского графа декларативного потока дан-
ных. Ее работа — автоматизация рутинного труда по на-
стройке элементов пользовательского интерфейса для
визуализации изменения какого-то значения.
Как и другие описательные системы, привязка данных,
вероятно, слишком медленная и сложная, ее, скорее все-
го, не внедрить в ядро игрового движка. Но я был бы удив-
лен, если бы не видел, что она начала проникать в менее
критичные с точки зрения производительности области
игры, такие как пользовательский интерфейс.
Тем временем старый добрый паттерн Наблюдатель
(Observer) все равно будет ждать нас. Конечно, его ис-
пользование менее захватывающе, чем внедрение мод-
ной техники, совмещающей слова «функциональное»
и «реактивное» в своем названии, но он чертовски прост
и работает. Для меня это два наиболее важных критерия
при выборе решения.
Do'stlaringiz bilan baham: |