2016-12-11 2 views
2

Я пишу диспетчер ресурсов, который может выделять уникальные идентификаторы (например, для одинаковых точек привязки буфера OpenGL, поэтому вам не нужно отслеживать используемые им), поэтому, если бы было больше экземпляров менеджера это будет проблемой, потому что каждый должен знать, какие идентификаторы уже используются. Так один из способов заключается в использовании Singleton:Singleton vs static members

class ResourceManager 
{ 
private: 
    HandleAllocator uniform_binding_points; 
    ... 
public: 
    static ResourceManager& Get() 
    { 
     static ResourceManager resource_manager; 
     return resource_manager; 
    } 
    unsigned int AllocateUniformBindingPoint() 
    { ... } 
    ... 
private: 
    ResourceManager() 
    { } 
    ~ResourceManager() 
    { } 
} 

Или использовать статические члены, так что может быть несколько экземпляров, но каждый экземпляр использует то же самое состояние:

class ResourceManager 
{ 
private: 
    static HandleAllocator uniform_binding_points; 
    ... 
public: 
    unsigned int AllocateUniformBindingPoint() 
    { ... } 
    ... 
} 

Так что мой вопрос какая разница, и есть ли лучшее решение (учитывая возможность проверки)? Я знаю, что многие люди ненавидят одиночные игры, но, на мой взгляд, единственное различие заключается в том, что вам нужно получить экземпляр Singleton с Get(), который является одним вызовом метода, но вы можете сохранить ссылку, чтобы вы вызывали Get() один раз. Также я прочитал это: http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/, и мне нужно сказать, что с составом и агрегацией вы можете добиться того же «скрытия зависимости», поэтому не используйте их тоже? ...

+1

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

ответ

2

Я думаю, что это стиль вопрос, поэтому нет определенного ответа. Тем не менее, я приведу несколько причин, почему я считаю, что синглтон является лучшим решением здесь.

Метод Get (обычно я нахожу его instance) четко заявляет, что это однотонный (по крайней мере, для тех, кто читает ваш документ, а ваш документ говорит, что это синглтон). У вас может быть несколько ссылок, инициализированных как

auto &mgr = ResourceManager::Get(); 

Но они все одинаковы. Это дает понять, что любая функция вызывает эти экземпляры - это вызовы на одном и том же объекте. И, таким образом, обычные инструкции могут быть более легко соблюдены. Например, если приложение является многопоточным, то мы знаем, что обычно не следует вызывать изменяемые методы одновременно на одном и том же объекте (при условии, что реализация ResourceManager соответствует таким рекомендациям). Теперь рассмотрим статический подход член,

ResourceManager mgr1; 
ResourceManager mgr2; 

Если я пользователь и не знает, как это реализовано, я не вижу никакого вреда в вызове двух изменяемых методов на каждом из этих двух объектов, которые не правда. Короче говоря, вы можете считать Singleton немного более «самодокументированным», по крайней мере, для пользователей, которые понимают, что такое Singleton.

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

И последнее, но не менее важное: singleton дает вам больше гибкости в управлении долголетием. В вашем примере используется одноэлемент Мейера и, следовательно, нет большой разницы. Но если возникнет такая необходимость, вы можете изменить реализацию singleton для точной настройки его долговечности

Смежные вопросы