logo

Wzorzec projektowy Singletona w Javie

  1. Wzorzec projektowy Singletona w Javie
  2. Zaleta wzorca Singletona
  3. Zastosowanie wzorca Singletona
  4. Przykład wzorca Singletona

Wzór Singleton tak właśnie mówi „zdefiniuj klasę, która ma tylko jedną instancję i zapewnia globalny punkt dostępu do niej”.

Innymi słowy, klasa musi zapewniać, że zostanie utworzona tylko jedna instancja, a wszystkie inne klasy będą mogły używać pojedynczego obiektu.

Istnieją dwie formy wzorca projektowego singletonu

  • Wczesna instancja: utworzenie instancji w czasie ładowania.
  • Leniwa instancja: utworzenie instancji w razie potrzeby.

Zaleta wzorca projektowego Singleton

  • Oszczędza pamięć, ponieważ obiekt nie jest tworzony przy każdym żądaniu. Tylko jedna instancja jest wielokrotnie wykorzystywana.

Zastosowanie wzorca projektowego Singleton

  • Wzorzec singletonu jest najczęściej używany w aplikacjach wielowątkowych i bazodanowych. Służy do rejestrowania, buforowania, pul wątków, ustawień konfiguracyjnych itp.

Uml wzorca projektowego Singleton


Jak stworzyć wzorzec projektowy Singleton?

Aby utworzyć klasę singleton, musimy mieć statycznego członka klasy, prywatnego konstruktora i statyczną metodę fabryczną.

  • Członek statyczny: Pobiera pamięć tylko raz ze względu na statyczność, zawiera instancję klasy Singleton.
  • Prywatny konstruktor: Zapobiegnie to utworzeniu instancji klasy Singleton spoza klasy.
  • Statyczna metoda fabryczna: Zapewnia to globalny punkt dostępu do obiektu Singleton i zwraca instancję do obiektu wywołującego.

Zrozumienie wczesnej instancji wzorca Singletona

W takim przypadku instancję klasy tworzymy w momencie zadeklarowania statycznego elementu danych, zatem instancja klasy tworzona jest w momencie ładowania klasy.

Zobaczmy przykład wzorca projektowego singletona wykorzystującego wczesną instancję.

Plik: A.java
 class A{ private static A obj=new A();//Early, instance will be created at load time private A(){} public static A getA(){ return obj; } public void doSomething(){ //write your code } } 

Zrozumienie leniwego tworzenia wzorca Singletona

W takim przypadku tworzymy instancję klasy w metodzie synchronized lub bloku synchronized, dzięki czemu instancja klasy jest tworzona w razie potrzeby.

Zobaczmy prosty przykład wzorca projektowego singletonu z wykorzystaniem leniwego tworzenia instancji.

Plik: A.java
 class A{ private static A obj; private A(){} public static A getA(){ if (obj == null){ synchronized(Singleton.class){ if (obj == null){ obj = new Singleton();//instance will be created at request time } } } return obj; } public void doSomething(){ //write your code } } 

Znaczenie modułu ładującego klasy we wzorcu Singleton

Jeśli klasa singleton jest ładowana przez dwa programy ładujące klasy, zostaną utworzone dwie instancje klasy singleton, po jednej dla każdego modułu ładującego klasy.


Znaczenie serializacji we wzorcu Singletona

Jeśli klasa singleton jest możliwa do serializacji, można serializować instancję singletonu. Po serializacji możesz go deserializować, ale nie zwróci to obiektu singleton.

kompozycja relacji

Aby rozwiązać ten problem, należy zastąpić plik metoda readResolve(). to wymusza singleton. Jest wywoływana tuż po deserializacji obiektu. Zwraca obiekt singleton.

 public class A implements Serializable { //your code of singleton protected Object readResolve() { return getA(); } } 

Zrozumienie prawdziwego przykładu wzorca Singletona

  • Zamierzamy utworzyć klasę JDBCSingleton. Ta klasa JDBCSingleton zawiera swój konstruktor jako prywatną i prywatną statyczną instancję jdbc.
  • Klasa JDBCSingleton zapewnia statyczną metodę przesyłania jej statycznej instancji do świata zewnętrznego. Teraz klasa JDBCSingletonDemo będzie używać klasy JDBCSingleton do pobrania obiektu JDBCSingleton.

Założenie: utworzyłeś tabelę userdata, która ma trzy pola uid, uname i upassword w bazie danych mysql. Nazwa bazy danych to ashwinirajput, nazwa użytkownika to root, hasło to ashwini.

Plik: JDBCSingleton.java
 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; class JDBCSingleton { //Step 1 // create a JDBCSingleton class. //static member holds only one instance of the JDBCSingleton class. private static JDBCSingleton jdbc; //JDBCSingleton prevents the instantiation from any other class. private JDBCSingleton() { } //Now we are providing gloabal point of access. public static JDBCSingleton getInstance() { if (jdbc==null) { jdbc=new JDBCSingleton(); } return jdbc; } // to get the connection from methods like insert, view etc. private static Connection getConnection()throws ClassNotFoundException, SQLException { Connection con=null; Class.forName('com.mysql.jdbc.Driver'); con= DriverManager.getConnection('jdbc:mysql://localhost:3306/ashwanirajput', 'root', 'ashwani'); return con; } //to insert the record into the database public int insert(String name, String pass) throws SQLException { Connection c=null; PreparedStatement ps=null; int recordCounter=0; try { c=this.getConnection(); ps=c.prepareStatement('insert into userdata(uname,upassword)values(?,?)'); ps.setString(1, name); ps.setString(2, pass); recordCounter=ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ if (ps!=null){ ps.close(); }if(c!=null){ c.close(); } } return recordCounter; } //to view the data from the database public void view(String name) throws SQLException { Connection con = null; PreparedStatement ps = null; ResultSet rs = null; try { con=this.getConnection(); ps=con.prepareStatement('select * from userdata where uname=?'); ps.setString(1, name); rs=ps.executeQuery(); while (rs.next()) { System.out.println('Name= '+rs.getString(2)+'	'+'Paasword= '+rs.getString(3)); } } catch (Exception e) { System.out.println(e);} finally{ if(rs!=null){ rs.close(); }if (ps!=null){ ps.close(); }if(con!=null){ con.close(); } } } // to update the password for the given username public int update(String name, String password) throws SQLException { Connection c=null; PreparedStatement ps=null; int recordCounter=0; try { c=this.getConnection(); ps=c.prepareStatement(' update userdata set upassword=? where uname=''+name+'' '); ps.setString(1, password); recordCounter=ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ if (ps!=null){ ps.close(); }if(c!=null){ c.close(); } } return recordCounter; } // to delete the data from the database public int delete(int userid) throws SQLException{ Connection c=null; PreparedStatement ps=null; int recordCounter=0; try { c=this.getConnection(); ps=c.prepareStatement(' delete from userdata where uid=''+userid+'' '); recordCounter=ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally{ if (ps!=null){ ps.close(); }if(c!=null){ c.close(); } } return recordCounter; } }// End of JDBCSingleton class 
Plik: JDBCSingletonDemo.java
 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; class JDBCSingletonDemo{ static int count=1; static int choice; public static void main(String[] args) throws IOException { JDBCSingleton jdbc= JDBCSingleton.getInstance(); BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); do{ System.out.println('DATABASE OPERATIONS'); System.out.println(' --------------------- '); System.out.println(' 1. Insertion '); System.out.println(' 2. View '); System.out.println(' 3. Delete '); System.out.println(' 4. Update '); System.out.println(' 5. Exit '); System.out.print('
'); System.out.print('Please enter the choice what you want to perform in the database: '); choice=Integer.parseInt(br.readLine()); switch(choice) { case 1:{ System.out.print('Enter the username you want to insert data into the database: '); String username=br.readLine(); System.out.print('Enter the password you want to insert data into the database: '); String password=br.readLine(); try { int i= jdbc.insert(username, password); if (i>0) { System.out.println((count++) + ' Data has been inserted successfully'); }else{ System.out.println('Data has not been inserted '); } } catch (Exception e) { System.out.println(e); } System.out.println('Press Enter key to continue...'); System.in.read(); }//End of case 1 break; case 2:{ System.out.print('Enter the username : '); String username=br.readLine(); try { jdbc.view(username); } catch (Exception e) { System.out.println(e); } System.out.println('Press Enter key to continue...'); System.in.read(); }//End of case 2 break; case 3:{ System.out.print('Enter the userid, you want to delete: '); int userid=Integer.parseInt(br.readLine()); try { int i= jdbc.delete(userid); if (i>0) { System.out.println((count++) + ' Data has been deleted successfully'); }else{ System.out.println('Data has not been deleted'); } } catch (Exception e) { System.out.println(e); } System.out.println('Press Enter key to continue...'); System.in.read(); }//End of case 3 break; case 4:{ System.out.print('Enter the username, you want to update: '); String username=br.readLine(); System.out.print('Enter the new password '); String password=br.readLine(); try { int i= jdbc.update(username, password); if (i>0) { System.out.println((count++) + ' Data has been updated successfully'); } } catch (Exception e) { System.out.println(e); } System.out.println('Press Enter key to continue...'); System.in.read(); }// end of case 4 break; default: return; } } while (choice!=4); } } 

pobierz ten przykład wzorca Singletona

Wyjście