2012-04-01 2 views
1

Это мой однопользовательский класс для получения соединения с базой данных.Почему это обязательное наличие частного конструктора внутри класса Singleton

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

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

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; 

     } 
    } 
+0

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

+2

Точно так же, как другие не будут получать доступ к вашим данным, если вы не объявите их частными: если вы единственный разработчик, работающий над проектом и имеющий полный контроль над ним, все в порядке. Но когда другие разработчики начнут в вашем проекте, они не будут знать, что им не разрешено создавать больше экземпляров вашего класса. И, кстати, вы тоже можете забыть об этом сами :) – Vlad

+0

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

ответ

1

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

14

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

+0

Почему другие создадут экземпляр моего класса Singleton, так как это мое приложение, и у меня есть полный контроль над этим? – user1254422

+2

Вы никогда не знаете, что произойдет с вашим приложением в другой день. Проект может расти, и вы получите в нем больше разработчиков. Так что, пока ваш проект действительно маленький, и у вас есть полный контроль над ним, вы можете делать это любым способом, как вам нравится, но как только проект становится более сложным, вам необходимо обеспечить соблюдение правила: «singleton is unique» , – Vlad

+2

@ user1254422 - Большинство людей работают в командах с более чем одним человеком, поэтому они говорят «другие». Однако, даже если это только вы, вы можете случайно создать несколько экземпляров, если не будете осторожны. Частный конструктор - это механизм безопасности, который предотвращает несколько экземпляров, поскольку единственный способ создать экземпляр - через метод статического get. –

4

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

6

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

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

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

5

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

3

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

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

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

5

Если вам не нужна ленивая инициация:

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; 
    } 
} 

это лучший способ, потому что это поточно.

3

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

enum Singleton { 
    INSTANCE 
} 

или

enum Utility {; 

} 

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

3

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

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