Site icon Khoa Phạm BK Blog

Design Pattern series: Giới thiệu Singleton

Singleton là 1 trong 5 design pattern của nhóm khởi tạo (Creational Design Pattern).

Định nghĩa:

Singleton is a creational design pattern that lets you ensure that a class has only one instance, while providing a global access point to this instance.

Dịch: Singleton là 1 mẫu design pattern thuộc nhóm khởi tạo cho phép bạn đảm bảo rằng 1 lớp sẽ chỉ có duy nhất 1 instance và nó cung cấp 1 method cho instance này ở bất cứ đâu trong chương trình.

Singleton giải quyết bài toán nào?

Singleton Pattern giải quyết 2 vấn đề dưới đây cùng 1 lúc:

Cách nó hoạt động sẽ như sau: Thử tưởng tượng rằng bạn đã tạo 1 object rồi, tuy nhiên sau đó bạn lại quyết định tạo thêm 1 object mới. Lúc này thay vì việc nhận được 1 object mới thì bạn sẽ nhận về object mà bạn tạo ra lúc trước.

Lưu ý rằng hành vi này không thể thực hiện với 1 phương thức khởi tạo thông thường (như sử dụng new), vì nó sẽ luôn trả về 1 object mới.

Có 1 cách nhìn khác cho vấn đề này: bạn không muốn phần code giải quyết vấn đề #1 ở trên bị phân tán khắp nơi trong chương trình, source code của mình. Sẽ tốt hơn khi chúng được viết hết trong 1 class đặc biệt là nếu các phần code khác đã phụ thuộc vào nó.

Cách triển khai Singleton

Tất cả các triển khai (implementations) của Singleton đều sẽ gồm 2 bước chung sau:

Nếu code của bạn truy cập đến lớp Singleton, nó có thể gọi đến phương thức static của Singleton, và sẽ luôn luôn được trả về chung 1 object.

Ví dụ thực tế

Singleton có nhiều ví dụ thực tế:

Cấu trúc, cách triển khai Singleton

Lớp Singleton khai báo phương thức static getInstance trả về cùng 1 instance của nó.

Phương thức khởi tạo Singleton nên được ẩn khỏi code client, cách duy nhất để lấy đối tượng Singleton là gọi phương thức getInstance.

Triển khai Singleton Pattern code với TypeScript

/**
 * The Singleton class defines the `getInstance` method that lets clients access
 * the unique singleton instance.
 */
class Singleton {
    private static instance: Singleton;

    /**
     * The Singleton's constructor should always be private to prevent direct
     * construction calls with the `new` operator.
     */
    private constructor() { }

    /**
     * The static method that controls the access to the singleton instance.
     *
     * This implementation let you subclass the Singleton class while keeping
     * just one instance of each subclass around.
     */
    public static getInstance(): Singleton {
        if (!Singleton.instance) {
            Singleton.instance = new Singleton();
        }

        return Singleton.instance;
    }

    /**
     * Finally, any singleton should define some business logic, which can be
     * executed on its instance.
     */
    public someBusinessLogic() {
        // ...
    }
}

/**
 * The client code.
 */
function clientCode() {
    const s1 = Singleton.getInstance();
    const s2 = Singleton.getInstance();

    if (s1 === s2) {
        console.log('Singleton works, both variables contain the same instance.');
    } else {
        console.log('Singleton failed, variables contain different instances.');
    }
}

clientCode();
Exit mobile version