Зачем использовать синглтон вместо статического класса? - PullRequest
39 голосов
/ 04 июня 2010

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

Ответы [ 7 ]

28 голосов
/ 04 июня 2010

Одной из веских причин для предпочтения синглтона над статическим классом (при условии, что в вашем распоряжении нет лучших образцов;)), является замена одного синглтонного экземпляра другим.

Например, если у меня есть такой класс журналирования:

public static class Logger {
    public static void Log(string s) { ... }
}

public class Client {
    public void DoSomething() {
        Logger.Log("DoSomething called");
    }
}

Это работает очень хорошо, но что, если Logger записывает данные в базу данных или выводит вывод на консоль. Если вы пишете тесты, вам, вероятно, не нужны все эти побочные эффекты, но поскольку метод log является статическим, вы ничего не можете сделать, кроме.

Хорошо, я хочу выполнить горячую замену метода журнала для тестирования. Иди иди гаджет синглтон!

public class Logger {
    private static Logger _instance;
    public static Logger Instance
    {
        get
        {
            if (_instance == null)
                _instance = new Logger();
            return _instance;
        }
        set { _instance = value; }
    }
    protected Logger() { }
    public virtual void Log(string s) { ... }
}

public class Client {
    public void DoSomething() {
        Logger.Instance.Log("DoSomething called");
    }
}

Таким образом, вы можете определить TestLogger : Logger с помощью пустого метода Log, а затем установить экземпляр вашего регистратора тестов на экземпляр singleton для тестов. Presto! Вы можете выполнить горячую замену своей реализации логгера для тестирования или производства, не затрагивая клиентский код.

10 голосов
/ 04 июня 2010

Синглтоны часто предпочитаются глобальным переменным, потому что:

  • Они не загрязняют глобальное пространство имен (или, в языках с пространствами имен, содержащим их пространство имен) ненужными переменными.
  • Они допускают ленивое распределение и инициализацию, тогда как глобальные переменные во многих языках всегда будут потреблять ресурсы.

Источник

EDIT:

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

7 голосов
/ 18 декабря 2010

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

public interface IFooProvider {
  Bar FooBar();
}

public static class Foo {
  public static readonly IFooProvider FooProvider { get; set; }
  public Bar FooBar() { return FooProvider.FooBar(); }
}

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

5 голосов
/ 04 июня 2010

Несмотря на то, что ИМХО шаблон синглтона является довольно часто используемым шаблоном, он иногда предлагает такие преимущества, как:

  • Возможность использовать различные типы объектов (которые наследуются от одной и той же базы) в качестве экземпляра (например, поставщики данных, в которых используется файловая система, а другая база данных SQL)
  • Сериализуемость. Я не использовал каркас, который может автоматически сериализовать статические классы.
  • Использование менее статичных полей. Для некоторых людей это скорее эстетическая особенность, но в некоторых случаях она имеет практические преимущества.
3 голосов
/ 04 июня 2010

Во многих языках статическим классам не хватает полезных функций, таких как наследование (и полиморфизм в целом).

( Не то чтобы я выступал за синглетонов .)

2 голосов
/ 23 января 2018
  1. Синглтон может реализовывать интерфейсы, наследовать от других классов
  2. Singleton может инициализироваться лениво или асинхронно и автоматически загружаться .NET Framework CLR (общеязыковая среда выполнения), когда загружается программа или пространство имен, содержащее класс. Хотя статический класс обычно инициализируется при первой загрузке, это может привести к потенциальным проблемам с загрузчиком классов.
  3. Синглтон-класс следует объектно-ориентированным принципам
  4. Объекты Singleton, хранящиеся в куче, в то время как статический класс хранится в стеке.
  5. Синглтон-объекты могут иметь конструктор, а статический класс - нет.
  6. Синглтон-объекты могут располагаться, но не статический класс
  7. Объекты-одиночки могут клонироваться, но не со статическим классом
2 голосов
/ 04 июня 2010

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

Также вы можете использовать синглтоны с интерфейсами, как и любой другой класс.

...