Почему в классе Singleton должен быть частный конструктор - PullRequest
4 голосов
/ 01 апреля 2012

Это мой одноэлементный класс для получения соединения с базой данных.

У меня здесь есть вопрос: почему необходимо иметь закрытый конструктор внутри одноэлементного класса (так как во всем моем приложении я вызываю этот класс только один раз) и как один экземпляр класса можно достичь с помощью статического метода?

Можно ли избежать этого частного конструктора или он является обязательным?

 public class ConnPoolFactory {
        private static DataSource dataSource;
        private static Connection connection;

        private ConnPoolFactory() {
            System.out.println(" ConnPoolFactory cons is called ");
        }

        public static synchronized Connection getConnection() throws SQLException {

            try {

                if (connection == null) {
                    Context initContext = new InitialContext();
                    Context envContext = (Context) initContext
                            .lookup("java:/comp/env");
                    dataSource = (DataSource) envContext.lookup("jdbc/Naresh");
                    connection = dataSource.getConnection();
                } else {
                    return connection;
                }

            } catch (NamingException e) {
                e.printStackTrace();
            }

            return connection;

        }
    }

Ответы [ 10 ]

17 голосов
/ 01 апреля 2012

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

6 голосов
/ 01 апреля 2012

Если вам не нужно ленивое посвящение:

public class Singleton {
    private static final Singleton instance = new Singleton();

    // Private constructor prevents instantiation from other classes
    private Singleton() { }

    public static Singleton getInstance() {
            return instance;
    }
}

- лучший способ, потому что потокобезопасен.

6 голосов
/ 01 апреля 2012

Шаблон Singleton обычно включает в себя непубличный конструктор по двум причинам.Конструктор должен существовать, потому что, если конструктора нет вообще, включается общедоступный конструктор по умолчанию.Если у вас есть публичный конструктор, однако, люди могут просто создавать свои собственные синглеты по желанию (что неизбежно будет, что означает, что их может быть больше одного).

Это не обязательно должно быть частным.На самом деле, как я слышал, шаблон Singleton, как указано в GoF, по какой-то странной причине упоминает конструктор защищенный .Я слышал кое-что о наследовании, но синглтоны и наследование все равно не очень хорошо сочетаются друг с другом.

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

5 голосов
/ 01 апреля 2012

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

4 голосов
/ 01 апреля 2012

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

3 голосов
/ 01 апреля 2012

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

enum Singleton {
     INSTANCE
}

или

enum Utility {;

}

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

3 голосов
/ 01 апреля 2012

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

Так что для класса Singleton, то есть класса, содержащего не более одного экземпляра, требуется частный конструктор.

В вашем примере, похоже, класс Singleton подходит больше, чем статический класс - из-за членов подключения и dataSource.Сделайте эти члены частными, ваш конструктор закрытыми и предоставьте статические методы, которые ссылаются на статический экземпляр ConnPoolFactory.Если экземпляр имеет значение null, создайте новый, в противном случае просто используйте его.

2 голосов
/ 01 апреля 2012

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

1 голос
/ 28 марта 2019

Синглтон по умолчанию:

Убедитесь, что для всего основного стека необходимо создать только один объект (для каждого основного класса).

Если вы хотите удовлетворить вышеупомянутое утверждение, тогда мы должны предоставить конструктор как приватный. На самом деле, через синглтон мы получаем ref, а не object, поэтому это не обязательно, тогда мы можем создать объект в других классах, но не можем получить доступ к ссылке (Constructor as public).

Ex:

public class SingleTon {

    private static SingleTon s;
    public SingleTon() {}

    public static SingleTon getInstance() {
        if (s == null) {
            s = new SingleTon();
            System.out.println("ho ho");
        } else{
            return s;
        }
        return s;
    }
}

Другой класс:

public class Demo {

    public static void main(String[] args) {
        //SingleTon s=SingleTon.getInstance();

        SingleTon s11=new SingleTon();
        SingleTon s12=new SingleTon();
        s11.getInstance();
        s12.getInstance();
    }
}

Выход:

ho ho
1 голос
/ 01 апреля 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...