2009-09-01 2 views
6

С точки зрения конечного пользователя API, которому необходимо «получить экземпляр« класса Singleton », вы предпочитаете« получать » . Свойство .Instance или« вызов ».GetInstance() Метод?C# Singleton Метод GetInstance или свойство «Instance»?

public class Bar 
{ 
    private Bar() { } 

    // Do you prefer a Property? 
    public static Bar Instance 
    { 
     get 
     { 
      return new Bar(); 
     } 
    } 

    // or, a Method? 
    public static Bar GetInstance() 
    { 
     return new Bar(); 
    } 
} 
+2

«получить экземпляр» должен действительно быть «получить экземпляр», а «новый» немного вводит в заблуждение; -p –

+0

@Marc Gravell - согласился. точка хорошо взята. thx – jlang

+0

Прошу подумать дважды, прежде чем писать синглтон. Я видел случаи, когда они вынуждали использовать интеграционные тесты над модульными тестами - доступ к базе данных в Singletons, а также к другим классам. См. Http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons – TrueWill

ответ

14

В C#, я бы предпочел далеко .Instance, как это согласуется с общими рекомендациями.

+1

+1 Согласен. Параметры пассирования также не нужны. – Mickel

+0

Влияния зависимостей Микеля в сочетании с одноэлементным рисунком? –

+0

Лично я даже не написал «Синглтон» для моего собственного законного, и я вообще сомневаюсь в его необходимости. –

3

Зависит. Вам нужно передать параметры? Если это так, я бы сделал GetInstance(). Если нет, возможно, это не имеет значения (по крайней мере, с точки зрения вызова, так как в любом случае они действительно оба метода, но это имеет значение, если вы пытаетесь быть более стандартными и, в этом случае, экземпляр оказывается лучше).

0

Я предпочитаю собственность, это стандартные образцы.

4

Как и почти все, это зависит :)

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

Если мы просто маскируем защиту экземпляра singleton, предпочтительным является свойство.

+0

Но специально для сингла, только первый вызов должен выполнять эту работу. Следующие вызовы должны просто вернуть ранее подготовленный экземпляр. –

+0

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

13

Если вы хотите создать singleton, вы не можете просто вернуть новый объект на каждый GetInstance звонок или Instance свойство getter. Вы должны сделать что-то вроде этого:

public sealed class Bar 
{ 
    private Bar() { } 

    // this will be initialized only once 
    private static Bar instance = new Bar(); 

    // Do you prefer a Property? 
    public static Bar Instance 
    { 
     get 
     { 
      return instance; 
     } 
    } 

    // or, a Method? 
    public static Bar GetInstance() 
    { 
     return instance; 
    } 
} 

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

+0

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

+2

Все действующие пункты; вероятно, он также должен быть «запечатан». –

+0

@RaYell Я думаю, что его пример кода - это просто показать разницу между свойством и методом. –

0

Как сказал @Rex, это зависит от семантики, которую вы хотите передать.

GetInstance() не обязательно означает экземпляр singleton. Таким образом, я бы использовал GetInstance() в случае, когда создание экземпляра происходит по запросу, direct new не является желательным, и экземпляр может быть, но не гарантируется, что он будет таким же. Пулы объектов также соответствуют этим критериям. (На самом деле, singleton является специализацией пула объектов с сохранением состояния :-))

Свойство Static Instance, с другой стороны, подразумевает идентичность одного и того же экземпляра.

Btw, as @RaYell отметил, что ваш пример кода не является одиночным, поэтому вы не должны использовать свойство экземпляра. Вы все равно можете использовать метод GetInstance() в этом случае, поскольку он будет служить фабрикой экземпляра.

2
public class Singleton 
{ 

    private volatile static Singleton uniqueInstance; 
    private static readonly object padlock = new object(); 

    private Singleton() { } 

    public static Singleton getInstance() 
    { 
     if (uniqueInstance == null) 
     { 
      lock (padlock) 
      { 
       if (uniqueInstance == null) 
       { 
        uniqueInstance = new Singleton(); 
       } 
      } 
     } 
     return uniqueInstance; 
    } 
} 

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

   if (uniqueInstance == null) 
       { 
        uniqueInstance = new Singleton(); 
       } 

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

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

+0

Хорошая блокировка двойной проверки.Хотя, если вам нужно всего лишь создать экземпляр вашего синглтона, используйте: private static readonly Singleton uniqueInstance = new Singleton(); – bryanbcook

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

  • Нет связанных вопросов^_^