Singleton Pattern – Code ví dụ Singleton Pattern bằng Java.

Singleton Pattern – Code ví dụ Singleton Pattern bằng Java.

1. Singleton Pattern là gì?

Singleton Pattern là 1 mẫu thiết kế tạo dựng (Creation Pattern)

Singleton Pattern được dùng để ngăn cản việc tạo các thể hiện của một lớp (class) nhằm đảm bảo rằng luôn chỉ có 1 thể hiện của class tồn tại trong JVM.

Class Singleton Pattern phải cung cấp 1 điểm truy cập global để lấy ra được thể hiện của class.

Singleton Pattern được dùng cho logging, các driver object, caching và thread pools.

Singleton Pattern cũng được sử dụng trong các Design Pattern khác như Abstract Factory, Builder, Facede…

Một số class Singleton trong Java core như java.lang.Runtimejava.awt.Desktop

(Luôn chỉ có nhiều nhất 1 object của class  java.lang.Runtimejava.awt.Desktop được tạo)

Singleton Pattern – Code ví dụ Singleton Pattern bằng Java.

2. Singleton Pattern UML Diagram.

Một Singleton Pattern thường là 1 class (Class Singleton) có các đặc điểm:

  • Hàm khởi tạo private để ngăn cản việc tạo thể hiện của class từ các class khác
  • Biến private static của class, nó là thể hiện duy nhất của class.
  • Method public static để trả về thể hiện của class.

Singleton Pattern - Code ví dụ Singleton Pattern bằng Java.

3. Cách tạo một class Singleton Pattern.

Cách 1: eager initialization

Thể hiện Singleton Class được tạo lúc class được tải , đây là cách dễ dàng nhất để tạo 1 singleton class nhưng nó có nhược điểm là thể hiện được tạo kể cả khi nó không được dùng đến, và không thể bắt được ngoại lệ lúc tạo thể hiện.

public class EagerInitializedSingleton {
    
    private static final EagerInitializedSingleton instance = new EagerInitializedSingleton();
    
    //private constructor to avoid client applications to use constructor
    private EagerInitializedSingleton(){}

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

 Cách 2: Static block initialization

Khởi tạo bằng static block, nó giống hệt cách 1 tuy nhiên có thể sử lý được ngoại lệ khi khởi tạo thể hiện đầu tiên.

public class StaticBlockSingleton {

    private static StaticBlockSingleton instance;
    
    private StaticBlockSingleton(){}
    
    //static block initialization for exception handling
    static{
        try{
            instance = new StaticBlockSingleton();
        }catch(Exception e){
            throw new RuntimeException("Exception occured in creating singleton instance");
        }
    }
    
    public static StaticBlockSingleton getInstance(){
        return instance;
    }
}

Cách 3: Lazy initialization

Tạo thể hiện của Class Singleton trong method access. Cách này có nhược điểm là không hoạt động đúng trong trường hợp có nhiều thread, giả sử có nhiều thread cùng lúc gọi method getInstance() sẽ có nhiều thể hiện khác nhau được tạo.

public class LazyInitializedSingleton {

    private static LazyInitializedSingleton instance;
    
    private LazyInitializedSingleton(){}
    
    public static LazyInitializedSingleton getInstance(){
        if(instance == null){
            instance = new LazyInitializedSingleton();
        }
        return instance;
    }
}

Cách 4: Thread Safe Singleton

Giống cách thứ 3 nhưng method getInstance() được đánh dấu là synchronized  tức là chỉ có duy nhất 1 thread được gọi đến nó trong 1 thời điểm.

public class ThreadSafeSingleton {

    private static ThreadSafeSingleton instance;
    
    private ThreadSafeSingleton(){}
    
    public static synchronized ThreadSafeSingleton getInstance(){
        if(instance == null){
            instance = new ThreadSafeSingleton();
        }
        return instance;
    }
    
}

Cách 5: Bill Pugh Singleton Implementation

Tạo thể hiện của class Singleton bằng static inner class.

Khi singleton class được tải, class SingletonHeplper vẫn không được tải vào bộ nhớ mà chỉ khi method getInstance() được gọi, class này mới được tải và tạo thể hiện cho Singleton class

Cách này cũng không yêu cầu synchronization.

public class BillPughSingleton {

    private BillPughSingleton(){}
    
    private static class SingletonHelper{
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }
    
    public static BillPughSingleton getInstance(){
        return SingletonHelper.INSTANCE;
    }
}

Cách 6: Sử dụng Enum

public enum EnumSingleton {
    INSTANCE;
    
    public static void doSomething(){
        //do something
    }
}

Ngoài ra còn một số cách ít dùng khác như “Using Reflection to destroy Singleton Pattern”, “Serialization and Singleton”…

 

Singleton Pattern – Code ví dụ Singleton Pattern bằng Java.

 

References: https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples

 

stackjava.com