Довольно прямой вопрос.
Что такое Singleton и когда я должен его использовать?
Довольно прямой вопрос.
Что такое Singleton и когда я должен его использовать?
Singleton - это класс, который позволяет только создать один экземпляр для себя - и дает простой и легкий доступ к указанному экземпляру. Одиночная посылка - образец для разработки программного обеспечения.
Существует реализация С# "Внедрение шаблона Singleton в С#" , охватывающая большую часть того, что вам нужно знать, включая некоторые полезные советы относительно безопасность потока.
Честно говоря, очень редко вам нужно реализовать синглтон - по-моему, это должна быть одна из тех вещей, о которых вы должны знать, даже если она не используется слишком часто.
Вы попросили С#. Тривиальный пример:
public class Singleton
{
private Singleton()
{
// Prevent outside instantiation
}
private static readonly Singleton _singleton = new Singleton();
public static Singleton GetSingleton()
{
return _singleton;
}
}
Что это такое: Класс, для которого есть только один, постоянный экземпляр на протяжении всего срока службы приложения. См. Шаблон Singleton.
Когда вы должны использовать его: Как можно меньше. Только когда вы абсолютно уверены, что вам это нужно. Я не хочу сказать "никогда", но обычно есть лучшая альтернатива, такая как инъекция зависимостей или просто статический класс.
Другой способ реализовать singleton в С#, я лично предпочитаю этот способ, потому что вы можете получить доступ к экземпляру класса singeton как свойство вместо метода.
public class Singleton
{
private static Singleton instance;
private Singleton() { }
public static Singleton Instance
{
get
{
if (instance == null)
instance = new Singleton();
return instance;
}
}
//instance methods
}
но хорошо, насколько я знаю, оба пути считаются "правильными", поэтому это просто личный вкус.
using System;
using System.Collections.Generic;
class MainApp
{
static void Main()
{
LoadBalancer oldbalancer = null;
for (int i = 0; i < 15; i++)
{
LoadBalancer balancerNew = LoadBalancer.GetLoadBalancer();
if (oldbalancer == balancerNew && oldbalancer != null)
{
Console.WriteLine("{0} SameInstance {1}", oldbalancer.Server, balancerNew.Server);
}
oldbalancer = balancerNew;
}
Console.ReadKey();
}
}
class LoadBalancer
{
private static LoadBalancer _instance;
private List<string> _servers = new List<string>();
private Random _random = new Random();
private static object syncLock = new object();
private LoadBalancer()
{
_servers.Add("ServerI");
_servers.Add("ServerII");
_servers.Add("ServerIII");
_servers.Add("ServerIV");
_servers.Add("ServerV");
}
public static LoadBalancer GetLoadBalancer()
{
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
{
_instance = new LoadBalancer();
}
}
}
return _instance;
}
public string Server
{
get
{
int r = _random.Next(_servers.Count);
return _servers[r].ToString();
}
}
}
Я взял код с dofactory.com, ничего особенного, но я нахожу это гораздо лучше, чем примеры с Foo and Bar, дополнительно в книге от Джудит Бишоп о С# 3.0 Design Patterns есть пример активного приложения в доке Mac.
Если вы посмотрите на код, мы фактически строим новые объекты для цикла for, так что он создает новый объект, но повторно использует экземпляр, в результате чего oldbalancer и newbalancer имеют один и тот же экземпляр. Как? Это происходит из-за того, что ключевое слово static используется в функции GetLoadBalancer(), несмотря на то, что сервер имеет другое значение, которое является случайным списком, static в GetLoadBalancer() принадлежит самому типу, а не конкретному объекту.
Дополнительно здесь есть двойная проверка блокировки
if (_instance == null)
{
lock (syncLock)
{
if (_instance == null)
так как из MSDN
Ключевое слово lock гарантирует, что один поток не войдет в критический раздел кода, в то время как другой поток находится в критическом разделе. Если другой поток попытается ввести заблокированный код, он будет ждать блокировки до тех пор, пока объект не будет освобожден.
поэтому каждый раз выдается блокировка взаимного исключения, даже если она не нужна, что является ненужным, поэтому у нас есть нулевая проверка.
Надеюсь, это поможет очистить больше.
И, пожалуйста, прокомментируйте, если я понимаю, что мое направление неверно.
A Singleton (и это не связано с С#, это шаблон проектирования OO) - это когда вы хотите разрешить только один экземпляр класса, который будет создан во всем приложении. Использования обычно включают глобальные ресурсы, хотя я скажу из личного опыта, что они часто являются источником большой боли.
В то время как только один экземпляр одного синглета может быть только один, это не то же самое, что и статический класс. Статический класс может содержать только статические методы и никогда не может быть инстанцирован, тогда как экземпляр singleton может использоваться так же, как любой другой объект.
Это шаблон дизайна, и он не специфичен для С#. Подробнее об этом по всему Интернету и SO, как на этой статье в википедии.
В разработке программного обеспечения синглтон шаблон представляет собой шаблон проектирования, который используется для ограничения экземпляра класс к одному объекту. Это полезно когда требуется один объект для координировать действия по всей системе. Концепция иногда обобщается к системам, которые работают больше эффективно, когда только один объект существует или ограничивает создание экземпляра определенного количества объектов (например, пять). Некоторые считают это анти-шаблон, судя по тому, что он чрезмерное использование, вводит ненужные ограничения в ситуациях, когда единственная экземпляр класса на самом деле не является требуется и вводит глобальное состояние в приложение.
Вы должны использовать его, если хотите класс, который может быть установлен только один раз.
Я использую его для данных поиска. Загрузите один раз из БД.
public sealed class APILookup
{
private static readonly APILookup _instance = new APILookup();
private Dictionary<string, int> _lookup;
private APILookup()
{
try
{
_lookup = Utility.GetLookup();
}
catch { }
}
static APILookup()
{
}
public static APILookup Instance
{
get
{
return _instance;
}
}
public Dictionary<string, int> GetLookup()
{
return _lookup;
}
}
Что такое синглтон:
Это класс, который позволяет создавать только один его экземпляр и обычно предоставляет простой доступ к этому экземпляру.
Когда вы должны использовать:
Это зависит от ситуации.
Примечание: пожалуйста, не используйте соединение с БД, подробный ответ см. В ответе @Chad Grant.
Вот простой пример Singleton
:
public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
private Singleton()
{
}
public static Singleton Instance
{
get
{
return instance;
}
}
}
Вы также можете использовать Lazy<T>
чтобы создать свой Singleton
.
Смотрите здесь для более подробного примера использования Lazy<T>
Вот какой синглтон: http://en.wikipedia.org/wiki/Singleton_pattern
Я не знаю С#, но на самом деле это то же самое на всех языках, только реализация отличается.
Обычно вам следует избегать синглотона, если это возможно, но в некоторых ситуациях это очень удобно.
Извините за мой английский;)
Класс Singleton используется для создания одного экземпляра для всего домена приложения.
public class Singleton
{
private static Singleton singletonInstance = CreateSingleton();
private Singleton()
{
}
private static Singleton CreateSingleton()
{
if (singletonInstance == null)
{
singletonInstance = new Singleton();
}
return singletonInstance;
}
public static Singleton Instance
{
get { return singletonInstance; }
}
}
В в этой статье описано, как мы можем создать потокобезопасный одноэлементный класс с использованием переменной readonly и их практическое использование в приложениях.
EX Вы можете использовать Singleton для глобальной информации, которую необходимо ввести.
В моем случае я хранил данные о зарегистрированном пользователе (имя пользователя, разрешения и т.д.) В глобальном статическом классе. И когда я попытался реализовать unit тест, я никак не мог внедрить зависимость в классы контроллера. Таким образом, я изменил свой статический класс на шаблон Singleton.
public class SysManager
{
private static readonly SysManager_instance = new SysManager();
static SysManager() {}
private SysManager(){}
public static SysManager Instance
{
get {return _instance;}
}
}
http://csharpindepth.com/Articles/General/Singleton.aspx#cctor
Я знаю, что очень поздно отвечать на вопрос, но с помощью Auto-Property вы можете сделать что-то подобное:
public static Singleton Instance { get; } = new Singleton();
Где Singleton
является вашим классом и может быть через, в этом случае только для чтения свойство Instance
.
Нам нужно использовать шаблон проектирования Singleton в С#, когда нам нужно убедиться, что будет создан только один экземпляр определенного класса, и затем обеспечить простой глобальный доступ к этому экземпляру для всего приложения.
Сценарии реального времени, в которых вы можете использовать шаблон проектирования Singleton: прокси-серверы службы. Как мы знаем, вызов API-интерфейса службы - это обширная операция в приложении. Процесс, который занимает большую часть времени, - это создание клиента службы для вызова API службы. Если вы создадите прокси-сервер службы как Singleton, это улучшит производительность вашего приложения.
Фасады: Вы также можете создавать подключения к базе данных как Singleton, что может повысить производительность приложения.
Журналы. В приложении выполнение операции ввода-вывода над файлом является дорогостоящей операцией. Если вы создадите Logger как Singleton, это улучшит производительность операции ввода-вывода.
Совместное использование данных: если у вас есть какие-либо постоянные значения или значения конфигурации, вы можете сохранить эти значения в Singleton, чтобы их могли прочитать другие компоненты приложения.
Кэширование. Как мы знаем, выборка данных из базы данных занимает много времени. В вашем приложении вы можете кэшировать мастер и конфигурацию в памяти, что позволит избежать вызовов БД. В таких ситуациях класс Singleton может использоваться для эффективной обработки кэширования с синхронизацией потоков, что значительно повышает производительность приложения.
Недостатки шаблона проектирования Singleton в С# Недостатки использования шаблона проектирования Singleton в С# заключаются в следующем:
Модульное тестирование очень сложно, потому что оно вводит глобальное состояние в приложение. Это снижает вероятность параллелизма внутри программы, поскольку для доступа к одноэлементному экземпляру в многопоточной среде необходимо сериализовать объект с помощью блокировки.
Я взял это из следующей статьи.
https://dotnettutorials.net/lesson/singleton-design-pattern/
Singleton - это тип удаленного объекта, который используется для обслуживания нескольких клиентов. Эти объекты сохраняют состояния, а не типы объектов вызова типа