Реализация шаблона проектирования Singleton [Пожалуйста, предложите] - PullRequest
1 голос
/ 19 августа 2011

Может ли кто-нибудь определить проблему в этом фрагменте кода Java / C #, реализующего шаблон проектирования Singleton.

Может кто-нибудь найти мне недостаток в этой реализации этого фрагмента?

class Singleton{
public static Singleton Instance() {
if (_instance == null)
_instance = new Singleton();
return _instance;
}
protected Singleton() {}
private static Singleton _instance = null;
}

Ответы [ 7 ]

9 голосов
/ 19 августа 2011

Это не потокобезопасно

http://csharpindepth.com/Articles/General/Singleton.aspx

3 голосов
/ 19 августа 2011

Как говорит Кирен, он не является поточно-ориентированным ... и также вы позволили классам наследовать его, что означает, что на самом деле это не одиночный код:

public class SingletonBasher : Singleton
{
}

Singleton x = Singleton.Instance();
Singleton y = new SingletonBasher();

Недопустимо, чтобы x и y были разными ссылками, и обе они должны быть ненулевыми - это нарушает концепцию синглтона.

(И да, я бы порекомендовал мою статью о реализации Singleton * тоже 1011 *:)

2 голосов
/ 19 августа 2011

Лучший способ реализовать синглтон (как «Эффективная Java» Джошуа Блоха) - это использовать enum:

enum Singleton {
    INSTANCE();
    private Singleton() {
       ....
    }
}

Если вы настаиваете на своем подходе, вам нужно сделать еще три вещи:

  • сделать конструктор частным (как советует Джон Скит)
  • сделать _instance изменчивым
  • двойная блокировка экземпляра ()
1 голос
/ 19 августа 2011
enum A { A; }

0 голосов
/ 19 августа 2011

Это не потокобезопасно.

Вы можете реализовать другим способом с предварительной инициализацией:

private static Singleton _instance = new Singleton();

public static Singleton Instance()
{
    return _instance;
}

Этот метод является поточно-ориентированным, так как вы возвращаете только экземпляр метода.

0 голосов
/ 19 августа 2011

Все вышеприведенные ответы верны.

В шаблоне проектирования Singleton вы не должны позволять другим создавать экземпляры для класса Singleton. Вы должны владеть своими собственными правами. Другой экземпляр может запросить у вас экземпляр синглтона. Поэтому конструктор должен / должен быть закрытым.

В вашем примере вы сделали его защищенным. В этом случае, если вы расширяете класс singleton, у вас есть возможность создать экземпляр из другого экземпляра. Эта возможность не должна предоставляться.

Сделайте конструктор частным в вашем фрагменте кода, а затем в его синглтон-классе.

0 голосов
/ 19 августа 2011

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

class Singleton{
    public static Singleton Instance() {
        if (_instance == null) {
            lock(typeof(Singleton)) {
                if (_instance == null) {
                    _instance = new Singleton();
                }
            }
        }
        return _instance;
    }
    protected Singleton() {}
    private static Singleton _instance = null;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...