Game Programming Patterns / Паттерны программирования в играх: 1.5. Singleton
| Английский оригинал | Перевод на русский | |
|---|---|---|
Сожалеем, но текст оригинала доступен только зарегистрированным пользователям. |
Это не глава, а аномалия. Deo 28.08.14 в 14:22 Эта глава - аномалия. Avejant 22.09.14 в 13:44 |
|
|
Любая другая глава в этой книге покажет вам как пользоваться архитектурным паттерном. Deo 28.08.14 в 14:23 |
||
|
Эта глава покажет вам как не использовать его. Deo 28.08.14 в 14:23 |
||
|
Вопреки благородным намерениям, паттерн Singleton, описанный Бандой Четверых, обычно больше вредит, чем помогает. Deo 28.08.14 в 15:00 |
||
|
Хотя они подчеркивают, что паттерн следует использовать аккуратно, в игровой индустрии частенько это послание пропускают мимо ушей. Deo 28.08.14 в 15:16 |
||
|
Однако, как и любой паттерн, применять его там, где ему не место, так же полезно, как лечить огнестрельное ранение шиной. Deo 28.08.14 в 15:21 |
||
|
Из-за чрезмерности его применения, почти вся эта глава будет посвящена тому, как его избегать. Но сначала давайте взглянем на сам паттерн. Deo 28.08.14 в 15:23 |
||
|
Когда индустрия почти полностью перешла с C на объектно-ориентированное программирование, встал вопрос "как мне получить экземпляр?" . Deo 28.08.14 в 19:00 |
||
|
Допустим, был метод, которые нужно вызвать, но не было экземпляра объекта, который бы немедленно этот метод предоставлял. Deo 29.08.14 в 07:52 |
||
|
Паттерн Singleton (другим словами, сделать такой метод глобальным) Deo 29.08.14 в 07:54 |
||
|
был простым выходом. Deo 29.08.14 в 07:54 |
||
|
Шаблон Singleton (Одиночка) Alkarion 05.09.14 в 14:04 |
||
|
Шаблоны проектирования кратко формулируют Singleton таким образом: Alkarion 05.09.14 в 14:13 |
||
|
Гарантирует, что у класса есть единственный экземпляр, и предоставляет глобальную точку доступа к нему. Alkarion 05.09.14 в 14:34 |
||
|
Разделим его по "и" и рассмотрим каждую часть отдельно. Alkarion 05.09.14 в 14:58 |
||
|
Ограничение класса единственным экземпляром Alkarion 05.09.14 в 14:59 |
||
|
Бывает, что класс не может работать правильно, если существует более чем один его экземпляр. Alkarion 05.09.14 в 15:08 |
||
|
В общем случае класс взаимодействует с внешней системой, которая содержит свое собственное глобальное состояние. Alkarion 05.09.14 в 16:00 |
||
|
Рассмотрим класс-обертку над API файловой системы. Deo 29.08.14 в 08:51 |
||
|
Файловые операции могут занимать прилично времени, поэтому наш класс выполняет их асинхронно. Deo 29.08.14 в 09:48 |
||
|
Значит несколько операций могут выполняться одновременно, и следовательно они должны координироваться между собой. Deo 29.08.14 в 09:57 |
||
|
Если мы вызвали запрос на создание файла, а потом еще один на удаление того же файла, наш класс должен убедиться, запросы не перекрывают друг друга. Deo 29.08.14 в 11:10 |
||
|
Чтобы сделать это, вызову внутри нашей обертки требуется иметь доступ к каждой предыдущей операции. Alkarion 08.09.14 в 04:06 |
||
|
Если бы пользователи могли неограниченно создавать экземпляры нашего класса, ни один экземпляр не имел бы способа осведомления об операции, которую начали другие экземпляры. Alkarion 08.09.14 в 04:14 |
||
|
Введём Singleton. Alkarion 17.09.14 в 04:05 |
||
|
Это предоставит способ для класса гарантировать на стадии компиляции, что существует только один экземпляр класса. Alkarion 17.09.14 в 04:07 |
||
|
Предоставление глобальной точки доступа Alkarion 17.09.14 в 04:09 |
||
|
Несколько различных систем в игре будут использовать нашу файловую оболочку: ведение логов, загрузка контента, сохранение состояния игры и т.д. Avejant 22.09.14 в 13:47 |
||
|
Если эти системы не могут создать собственные экземпляры нашей файловой оболочки, как они могут получить доступ к ней? Avejant 22.09.14 в 13:51 |
||
|
Singleton обеспечивает решение и для этого. Avejant 22.09.14 в 13:47 |
||
|
В дополнение к созданию единственного экземпляра, он также обеспечивает глобальный метод доступа, чтобы получить его. Avejant 22.09.14 в 13:52 |
||
|
Таким образом, кто угодно и когда угодно может сунуть свои лапы в наш благословенный экземпляр. Avejant 22.09.14 в 13:53 |
||
|
Итак, классическое представление выглядит вот так: stfbee 30.04.14 в 12:41 |
||
|
class FileSystem stfbee 30.04.14 в 12:41 |
||
|
{ stfbee 30.04.14 в 12:42 |
||
|
public: stfbee 30.04.14 в 12:42 |
||
|
static FileSystem& instance() stfbee 30.04.14 в 12:42 |
||
|
{ stfbee 30.04.14 в 12:42 |
||
|
// Lazy initialize. stfbee 30.04.14 в 12:42 |
||
|
if (instance_ == NULL) stfbee 30.04.14 в 12:42 |
||
|
instance_ = new FileSystem(); stfbee 30.04.14 в 12:42 |
||
|
return *instance_; stfbee 30.04.14 в 12:43 |
||
|
} stfbee 30.04.14 в 12:43 |
||
|
private: stfbee 30.04.14 в 12:43 |
||
|
FileSystem() {} stfbee 30.04.14 в 12:43 |
||
|
static FileSystem* instance_; stfbee 30.04.14 в 12:43 |
||
|
}; stfbee 30.04.14 в 12:43 |
||
|
член static instance_ содержит екземпляр класа, и приватный конструктор проверяет что он всего один. warchief 05.03.15 в 22:18 |
||
|
метод public static instance() обеспечивает доступ к екземпляру из любого места в коде. warchief 05.03.15 в 22:20 Метод public static instance() обеспечивает доступ к экземпляру из любого места в коде. BaMnup16 08.03.16 в 18:36 |
||
|
Он также ответственен за ленивое создание экземпляра синглетона при первом запросе. BaMnup16 08.03.16 в 18:38 |
