Плохо ли использование синглтона в качестве класса менеджера данных? - PullRequest
7 голосов
/ 03 января 2012

Я обычно создаю приложения, которые требуют хранения данных, и эти данные используются во всей программе. Это не так много, поэтому я обычно использую NSUserDefaults для загрузки / сохранения этих данных. Однако код сохранения / загрузки, а также упаковка / распаковка данных занимают место, и я подумал, что было бы неплохо переместить этот код в методы многократного использования в глобальном синглтоне. Кажется, это сработало хорошо.

Несмотря на это, в последнее время я много читал о пороках синглетонов и глобальных объектов, и у меня появились вторые мысли. Люди часто говорят, что использование синглетонов почти всегда является признаком плохого дизайна. По большей части, я не согласен (я думаю, что простое использование, как это хороший шаблон проектирования), но я, конечно, не эксперт в этом вопросе.

Итак, плохо ли пользоваться синглетами, как это просто? Если да, то какая альтернатива лучше?

1 Ответ

5 голосов
/ 03 января 2012

Я определенно не согласен с тем, что одиночки - это зло. Возможно, их иногда используют слишком часто, но в некоторых случаях они идеально подходят для работы. В некоторых приложениях имеет смысл иметь какой-то общий менеджер данных. Шаблон Singleton широко используется в самом SDK (делегаты приложений, общие менеджеры, центры по умолчанию и т. Д.). Чаще всего это не «чистые» синглтоны, так как вы можете получить доступ к общему экземпляру, но также можете создавать новые экземпляры, если это необходимо.

Вопрос, который вам нужно задать себе, состоит в том, было бы полезно иметь доступ к одному экземпляру диспетчера данных из любого места в любое время, а если это не так, то, вероятно, единственная единица не нужна. Однако если вы собираетесь использовать синглтоны в многопоточных средах, вам нужно беспокоиться о состоянии гонки (может ли один поток изменить ресурс, пока другой обращается к нему), в документации есть хорошие объяснения того, как наилучшим образом добиться этого в Какао. .

Позвольте мне попытаться объяснить на примере - я использую некоторый код из игры, которую я написал. Допустим, у вас есть класс GameMap и класс Tile. GameMap представляет двумерную сетку из Tile объектов.

GameMap *gameMap = [[GameMap alloc] init];
NSArray *theTiles = gameMap.tiles;

Экземпляр GameMap владеет сеткой плиток и создает плитки при создании игровой карты. Синглтон не нужен.

Вы можете сказать: «Но у меня есть только один GameMap за раз, в чем дело?». Как насчет загрузки сохраненных игр или загрузки новых уровней? Ну, это становится так же просто, как:

// In whatever class object owns the game map
self.gameMap = [[GameMap alloc] initWithSaveData:saveData];

В заключение создайте экземпляр класса, в котором есть код для управления другими экземплярами вещей. Сохраняйте как можно меньше глобальных значений, и ваш код будет более масштабируемым и поддерживаемым.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...