Singleton Design Pattern trong JavaScript là một mẫu thiết kế mà chỉ cho phép tạo một thể hiện duy nhất của một lớp hoặc đối tượng, và mọi yêu cầu về thể hiện sau đó sẽ trả về thể hiện ban đầu. Đây là một cách để đảm bảo rằng một lớp chỉ có một thể hiện và cung cấp một điểm truy cập toàn cục cho nó.

Dưới đây là cách triển khai Singleton Pattern trong JavaScript:

Triển khai Singleton với IIFE (Immediately Invoked Function Expression)

Bạn có thể sử dụng IIFE để tạo ra một Singleton. IIFE giúp tạo ra một không gian phạm vi (scope) riêng và chỉ tạo ra thể hiện duy nhất khi cần.

const Singleton = (function () {
    let instance;

    function createInstance() {
        const object = new Object('I am the instance');
        return object;
    }

    return {
        getInstance: function () {
            if (!instance) {
                instance = createInstance();
            }
            return instance;
        }
    };
})();

// Sử dụng Singleton
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();

console.log(instance1 === instance2); // true

Giải thích:

  • instance: Được dùng để lưu trữ thể hiện duy nhất của đối tượng.
  • createInstance(): Hàm tạo một đối tượng mới nếu chưa có thể hiện nào.
  • getInstance(): Kiểm tra xem đã có một thể hiện tồn tại hay chưa. Nếu chưa có, nó sẽ tạo mới. Nếu đã có, nó trả về thể hiện hiện có.

Triển khai Singleton bằng ES6 Class

Với cú pháp ES6, bạn có thể tạo Singleton dễ dàng hơn bằng cách sử dụng class và đảm bảo rằng thể hiện chỉ được tạo một lần.

class Singleton {
    constructor() {
        if (Singleton.instance) {
            return Singleton.instance;
        }
        Singleton.instance = this;
        this.data = 'I am the instance';
    }

    getData() {
        return this.data;
    }
}

// Sử dụng Singleton
const singleton1 = new Singleton();
const singleton2 = new Singleton();

console.log(singleton1 === singleton2); // true

Giải thích:

  • Singleton.instance: Thuộc tính tĩnh của lớp để lưu trữ thể hiện duy nhất.
  • Trong phương thức constructor, nếu Singleton.instance đã tồn tại, nó sẽ trả về thể hiện đó thay vì tạo một thể hiện mới.
  • Mọi lần khởi tạo sau đều sẽ trả về thể hiện đầu tiên của lớp.

Triển khai Singleton bằng Module Pattern

Module Pattern cũng là một cách tốt để tạo Singleton trong JavaScript. Nó cho phép bạn kiểm soát quyền truy cập vào đối tượng và chỉ tạo ra thể hiện khi cần thiết.

const SingletonModule = (function () {
    let instance;

    function init() {
        // Private properties and methods
        const privateVariable = 'I am private';
        const privateMethod = () => {
            console.log('Private method');
        };

        return {
            // Public methods and properties
            publicMethod: function () {
                console.log('I am public');
            },
            publicProperty: 'I am also public',
            getPrivateVariable: function () {
                return privateVariable;
            }
        };
    }

    return {
        getInstance: function () {
            if (!instance) {
                instance = init();
            }
            return instance;
        }
    };
})();

// Sử dụng Singleton
const moduleInstance1 = SingletonModule.getInstance();
const moduleInstance2 = SingletonModule.getInstance();

console.log(moduleInstance1 === moduleInstance2); // true
console.log(moduleInstance1.getPrivateVariable()); // 'I am private'

Giải thích:

  • init(): Hàm khởi tạo tạo ra một đối tượng với các thuộc tính và phương thức riêng tư (private).
  • getInstance(): Kiểm tra xem thể hiện đã tồn tại hay chưa và tạo mới nếu cần.
  • Mọi truy cập vào đối tượng Singleton phải thông qua SingletonModule.getInstance().

Kết Luận

  • Singleton Design Pattern giúp tạo ra một thể hiện duy nhất của một lớp hoặc đối tượng trong toàn bộ ứng dụng.
  • Có thể triển khai Singleton bằng nhiều cách trong JavaScript, bao gồm IIFE, ES6 Class, và Module Pattern.
  • Singleton thường được sử dụng để quản lý trạng thái dùng chung, các thiết lập cấu hình hoặc các tài nguyên mà chỉ cần một bản thể.

Việc hiểu rõ và sử dụng đúng Singleton Pattern sẽ giúp tối ưu hóa bộ nhớ và quản lý tài nguyên hiệu quả hơn trong ứng dụng JavaScript.