Выдержка из единого кода, вопрос-интервью - PullRequest
6 голосов
/ 18 июня 2009

У меня был еще один вопрос для интервью. Я думал, что это глупо, но, возможно, что-то мне не хватает. Был задан вопрос о том, что это за паттерн GoF (ответ: синглтон), и, если есть какие-то проблемы, как я их решаю.

Я не вижу проблем. Я упоминал, что это никогда не освобождается, и я ожидаю, что от этого образца. Это все, что я сказал. Я что-то упустил?

public class Class1
{
    private static Class1 oInstance = null;
    private Class1() { }
    public static Class1 GetInstance()
    {
        if (oInstance == null)
        {
            oInstance  = new Class1();
        }
        return oInstance ;
    }
}

Ответы [ 9 ]

16 голосов
/ 18 июня 2009

Потокобезопасность - можно создать несколько экземпляров, если GetInstance () вызывается из конкурирующих потоков.

13 голосов
/ 18 июня 2009

См .: Очевидная одноэлементная реализация для .NET?

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

  • Что происходит, когда несколько абонентов запрашивают синглтон из нескольких потоков . Это должно просто работать.
  • Когда вызывается экземпляр Singleton , конструктор . Возможно, вы захотите отложить его, чтобы это произошло при первом вызове, запрашивающем синглтон, или, возможно, вы захотите сначала создать его экземпляр в другое время.
  • Должны ли люди наследовать от вашего синглтон-класса? Каким должно быть поведение?
  • Должна ли быть возможность переключить ваш экземпляр синглтона на другой экземпляр после того, как экземпляр был создан. Ответ «да» нарушает шаблон синглтона, поэтому в общем случае поле, содержащее синглтоны, должно быть readonly .
  • Дизайн API, если вы используете свойство или метод для возврата экземпляра Singleton.
  • Некоторые люди говорят, что синглтоны - это зло . Если вы вообще обдумываете это в первую очередь. Это обсуждалось довольно часто, хорошей отправной точкой является http://blogs.msdn.com/scottdensmore/archive/2004/05/25/140827.aspx

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

public sealed class Singleton
{
    static class SingletonCreator
    {
        // This may seem odd: read about this at: http://www.yoda.arachsys.com/csharp/beforefieldinit.html
        static SingletonCreator() {}
        internal static readonly Singleton Instance = new Singleton();
    }

    public static Singleton Instance
    {
        get { return SingletonCreator.Instance; }
    }
}
6 голосов
/ 18 июня 2009

Другие упоминали о безопасности потока. Также есть тот факт, что они забыли пометить его как sealed, и вы можете наследовать его и создавать несколько экземпляров таким образом.

3 голосов
/ 18 июня 2009

Код не является потокобезопасным. Для этого нужно сделать следующее:

public class Class1
{
    private static Class1 oInstance = null;
    private Class1() { }
    public static Class1 GetInstance()
    {
        if (oInstance == null)
        {
            lock(typeof(Class1))
            {
                if (oInstance == null)
                {
                    oInstance = new Class1();
                }
            }
        }
        return oInstance ;
    }
}

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

3 голосов
/ 18 июня 2009

У вас есть потенциальное состояние гонки в многопоточном коде. Каждый из двух потоков может пройти проверку на нулевое значение до завершения конструктора в другом потоке, так что оба могут завершить создание класса.

1 голос
/ 18 июня 2009

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

Я бы посмотрел на эту страницу на Singletons в C # . Подробно показывает проблему, а также лучшие варианты.

0 голосов
/ 18 июня 2009

В ней отсутствует безопасность потоков, эта страница действительно хорошо объясняет.

0 голосов
/ 18 июня 2009

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

0 голосов
/ 18 июня 2009

так что решение следующее?

public class Class1
{
    private static Class1 oInstance = new Class1();
    private Class1() { }
    public static Class1 GetInstance()
    {
        return oInstance ;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...