Использование синглтона вместо глобального статического экземпляра - PullRequest
8 голосов
/ 07 апреля 2010

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

Справочная информация: я пытаюсь создать экземпляр API и использовать этот экземпляр во всех моих классах (в отличие от созданияновое соединение и т. д.).

Кажется, существует около 100 способов создания синглтона, но с некоторой помощью yoda я нашел несколько потоковых примеров...so, учитывая следующий код:

public sealed class Singleton
{
     public static Singleton Instance { get; private set; }

     private Singleton()
     {
        APIClass api = new APIClass();  //Can this be done?
     }

     static Singleton() { Instance = new Singleton(); }
}

Как / Где бы вы создали экземпляр этого нового класса и как он должен вызываться из отдельного класса?

РЕДАКТИРОВАТЬ: я понимаю, Singletonкласс можно вызывать с чем-то вроде

Singleton obj1 = Singleton.Instance();

, но смогу ли я получить доступ к методам внутри класса API (т. е. obj1.Start)?(не то, что мне нужно, просто спрашиваю)

РЕДАКТИРОВАТЬ # 2: Я мог бы быть немного преждевременным при проверке ответа, но у меня есть одна маленькая вещь, которая все еще вызывает у меня проблемы.API запускается просто отлично, к сожалению, я могу запустить два экземпляра?

Новый код

public sealed class SingletonAPI
{
 public static SingletonAPI Instance { get; private set; }

 private SingletonAPI() {}

 static SingletonAPI() { Instance = new SingletonAPI(); }     

 // API method:
 public void Start() { API myAPI = new API();}
 }

, но если я попытаюсь сделать что-то подобное ...

SingletonAPI api = SingletonAPI.Instance;
api.Start();
SingletonAPI api2 = SingletonAPI.Instance;  // This was just for testing.
api2.Start();

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

Ответы [ 3 ]

9 голосов
/ 07 апреля 2010

Почему бы просто не добавить общедоступное свойство APIClass к вашему синглтону?

public sealed class Singleton
{
     public static Singleton Instance { get; private set; }

     private APIClass _APIClass; 

     private Singleton()
     {
        _APIClass = new APIClass();  
     }

     public APIClass API { get { return _APIClass; } }

     static Singleton() { Instance = new Singleton(); }     
}

Тогда ваш вызывающий сайт будет выглядеть так:

Singleton.Instance.API.DoSomething();

Или если вы являетесь автором класса API, вы можете сделать его одиночным, а не оборачивать его в одиночный:

public sealed class SingletonAPI
{
     public static SingletonAPI Instance { get; private set; }

     private SingletonAPI() {}

     static SingletonAPI() { Instance = new SingletonAPI(); }     

     // API method:
     public void DoSomething() { Console.WriteLine("hi"); }
}

Вызов API:

SingletonAPI.Instance.DoSomething();
5 голосов
/ 07 апреля 2010

Вот официальный подход Microsoft .

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

Singleton.Instance.MyValue и Singleton.Instance.DoSomething ();

3 голосов
/ 07 апреля 2010

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

Все, что вам нужно сделать, чтобы использовать это, это сделать:

 Singleton.Instance.MyMethodOnSingleton();

Или, альтернативно:

 Singleton myInstance = Singleton.Instance; // Will always be the same instance...
 myInstance.DoSomething();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...