Game Programming Patterns / Паттерны программирования в играх: 4.3 Service Locator
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Цель bubenok 03.07.14 в 16:35 |
|
|
Обеспечить глобальную точку доступа к службе без привязки пользователей к конкретному классу, который это реализует. bubenok 03.07.14 в 16:37 |
||
|
Причина bubenok 03.07.14 в 16:38 |
||
|
Некоторые объекты или системы игры используются практически в каждом уголке нашего кода. bubenok 03.07.14 в 17:10 |
||
|
Достаточно трудно найти ту часть игры, которая не нуждается в распределении памяти, логировании, файловой системе или случайных числах. bubenok 03.07.14 в 17:17 |
||
|
Такие системы можно рассматривать как службы, которые должны быть доступны всей игре. bubenok 03.07.14 в 17:21 |
||
|
К примеру, возьмем аудио. bubenok 03.07.14 в 17:22 |
||
|
Конечно, тут нет настолько низкоуровневых вещей, как в распределении памяти, но тем не менее аудио затрагивает большое количество игровых систем: падение камня на землю должно сопровождаться грохотом (физика). bubenok 04.07.14 в 04:13 |
||
|
Снайпер стреляет из своего оружия и раздается звук выстрела (ИИ). bubenok 04.07.14 в 12:16 |
||
|
Выбор пользователем пункта меню сопровождается звуковым сигналом подтверждения (пользовательский интерфейс). bubenok 04.07.14 в 12:17 |
||
|
Каждая из перечисленных частей игры должна иметь возможность обращаться к системе воспроизведения аудио каким либо способом: bubenok 04.07.14 в 12:19 Каждая из перечисленных частей игры должна уметь вызывать аудио подсистему, приблизительно такими способами: Deo 26.08.14 в 06:09 |
||
|
// Статический класс? bubenok 04.07.14 в 12:20 // Использовать статический класс? Deo 26.08.14 в 06:09 |
||
|
AudioSystem::playSound(VERY_LOUD_BANG) bubenok 04.07.14 в 12:20 |
||
|
; bubenok 04.07.14 в 12:20 |
||
|
// А может Singleton? bubenok 04.07.14 в 12:21 |
||
|
AudioSystem::instance()->playSound(VERY_LOUD_BANG) bubenok 04.07.14 в 12:21 |
||
|
; bubenok 04.07.14 в 12:21 |
||
|
Каждый способ приводит к цели, но по пути мы намертво к нему привязваемся. Deo 26.08.14 в 06:12 |
||
|
Каждое место в игре вызывая нашу аудио подсистему напрямую ссылается на конкретный класс AudioSystem и механизм доступа к нему - либо через статический класс, либо через синглтон. Deo 26.08.14 в 06:15 |
||
|
Конечно, чтобы воспроизводить звуки, эти вызовы должны быть привязаны к чему-либо, но позволяя им напрямую тыкать в конкретную аудио реализацию - это как дать сотне незнакомцев ваш адрес, только чтобы они забросили письмо к вам на порог. Deo 26.08.14 в 06:21 |
||
|
Кроме того, что это слишком личное, при переезде вы получите головную боль, обьясняя всем новый маршрут. Deo 26.08.14 в 06:24 |
||
|
Есть решение получше: телефонная книга. Deo 26.08.14 в 06:25 |
||
|
Люди, которые хотят с нами связаться, могут найти нас по имени и получить наш текущий адрес. Deo 26.08.14 в 06:25 |
||
|
При переезде мы уведомляем об этом телефонную компанию. Deo 26.08.14 в 06:27 |
||
|
Они обновляют книгу, и все получают новый адрес. Deo 26.08.14 в 06:27 |
||
|
Вообще-то, мы даже совсем не обязаны предоставлять свой реальный адрес. Deo 26.08.14 в 06:28 |
||
|
Заставляя вызывающую сторону заглянуть в телефонную книгу, чтобы нас найти, мы получаем удобное единственное место, где контролируем как нас найти. Deo 26.08.14 в 06:30 |
||
|
Так работает паттерн Service Locator: он отделяет код, которому требуется служба, и от того что это за служба (от конкретной реализации типа), Deo 26.08.14 в 06:32 |
||
|
и от того, где она расположена (как мы получаем ее экземпляр). Deo 26.08.14 в 06:32 |
||
|
Класс службы определяет абстрактный интерфейс к набору операций. Deo 26.08.14 в 06:35 |
||
|
Конкретный поставщик службы реализует этот интерфейс. Deo 26.08.14 в 06:34 |
||
|
Отдельно взятый Service Locator предоставляет доступ к службе, отыскивая подходящего поставщика, в то же время скрывая как его конкретный тип, так и алгоритм поиска. Deo 26.08.14 в 18:30 |
||
|
Когда использовать Deo 26.08.14 в 18:01 |
||
|
Каждый раз, когда делаете что-нибудь доступным всем частям вашей программы, вы ищите неприятностей. Deo 26.08.14 в 18:03 |
||
|
Это основная проблема паттерна Singleton, и этот паттерн не исключение. Deo 26.08.14 в 18:04 |
||
|
Мой простейший совет о том, как использовать Service Locator - используйте экономно. Deo 26.08.14 в 18:05 |
||
|
Вместо использования глобального механизма для предоставления некоторому коду доступа к нужному ему объекту, сперва рассмотрите возможность просто передать объект ему. Deo 26.08.14 в 18:07 |
||
|
Просто как 5 копеек, и делает связывание очевидным. Deo 26.08.14 в 18:10 |
||
|
Охватывает большую часть ваших ситуаций. Deo 26.08.14 в 18:12 |
||
|
Но...бывают случаи, когда передача объекта "вручную" неуместна, или сильно "засоряет" код. Deo 26.08.14 в 18:36 |
||
|
Некоторые подсистемы, такие как логирование и управление памятью, не должны быть частью открытого API. Deo 26.08.14 в 18:38 |
||
|
А параметры в коде, отвечающем за рендеринг должны относиться к рендерингу, а не к таким штукам как логирование. Deo 26.08.14 в 18:39 |
||
|
Ваша игра, скорее всего, взаимодействует лишь с одним аудио устройством или видео системой. Deo 26.08.14 в 18:44 |
||
|
Это естественное свойство среды, поэтому проводить его через 10 слоев методов , только чтобы один глубоко вложенный метод мог его вызвать, значит добавлять ненужную сложность в ваш код. Deo 26.08.14 в 18:54 |
||
|
В таких случаях, этот паттерн может помочь. Deo 26.08.14 в 18:55 |
