Шаблон "одиночка" для [закрытого] C#

15
задан cam 19 April 2010 в 11:42
поделиться

4 ответа

Обычно синглтон не статический класс - синглтон даст вам единственный экземпляр класс.

Я не знаю, какие примеры вы видели, но обычно шаблон синглтона может быть очень простым в C #:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton();
    static Singleton() {} // Make sure it's truly lazy
    private Singleton() {} // Prevent instantiation outside

    public static Singleton Instance { get { return instance; } }
}

Это несложно.

Преимущество синглтона над статическими членами состоит в том, что класс может реализовывать интерфейсы и т. Д. Иногда это полезно, но в других случаях статические члены действительно подойдут. Кроме того, обычно легче перейти от синглтона к не-синглтону позже, например передача синглтона в качестве объекта "конфигурации" классам зависимостей, а не тем классам зависимостей, которые выполняют прямые статические вызовы.

Лично я стараюсь по возможности избегать использования синглтонов - они усложняют тестирование, помимо всего прочего. Хотя иногда они могут быть полезны.

38
ответ дан 1 December 2019 в 00:29
поделиться

Есть несколько шаблонов, которые могут вам подойти, одноэлементный один из худших.

Реестр

struct Data {
  public String ProgramName;
  public String Parameters;
}

class FooRegistry {
  private static Dictionary<String, Data> registry = new Dictionary<String, Data>();
  public static void Register(String key, Data data) {
     FooRegistry.registry[key] = data;
  }
  public static void Get(String key) {
     // Omitted: Check if key exists
     return FooRegistry.registry[key];
  }
}

Преимущества

  • Легко переключиться на фиктивный объект для автоматического тестирования
  • Вы по-прежнему можете хранить несколько экземпляров, но при необходимости у вас есть только один экземпляр.

Недостатки

  • Немного медленнее, чем синглтон или глобальная переменная

Статический класс

class GlobalStuff {
  public static String ProgramName {get;set;}
  public static String Parameters {get;set;}
  private GlobalStuff() {}
}

Преимущества

  • Простой
  • Быстрый

Недостатки

  • Трудно динамически переключаться на фиктивный объект
  • Трудно переключиться на другой тип объекта при изменении требований

Простой синглтон

class DataSingleton {
  private static DataSingleton instance = null;
  private DataSingleton() {}
  public static DataSingleton Instance {
     get {
         if (DataSingleton.instance == null) DataSingleton.instance = new DataSingleton();
         return DataSingleton;
     }
  }
}

Преимущества

  • На самом деле нет

Недостатки

  • Трудно создать потокобезопасный синглтон, приведенная выше версия будет сбой, если к экземпляру обращаются несколько потоков.
  • Трудно переключиться на фиктивный объект

Лично мне нравится шаблон реестра, но YMMV.

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

Внедрение зависимостей

8
ответ дан 1 December 2019 в 00:29
поделиться

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

Типичный код .NET для синглтона выглядит примерно так. Это быстрый пример, и это ни в коем случае не лучшая реализация или потокобезопасный код :

public sealed class Singleton
{
    Singleton _instance = null;

    public Singleton Instance
    {
        get
        {
            if(_instance == null)
                _instance = new Singleton();

            return _instance;
        }
    }

    // Default private constructor so only we can instanctiate
    private Singleton() { }

    // Default private static constructor
    private static Singleton() { }
}

Если вы собираетесь пойти по пути, о котором думаете, статический запечатанный класс будет работать просто хорошо.

3
ответ дан 1 December 2019 в 00:29
поделиться

Насколько мне известно, это наиболее краткая и простая реализация шаблона Singleton на C #.

http://blueonionsoftware.com/blog.aspx?p=c6e72c38-2839-4696-990a-3fbf9b2b0ba4

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

http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx

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

http://houseofbilz.com/archive/2009/05/02.aspx

-1
ответ дан 1 December 2019 в 00:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: