Chả là tôi muốn trao đổi giá trị giữa 2 modules của Node.js, khách thì chuẩn bị sút vào đít rồi mà giờ vẫn đang loay hoay chưa biết phải làm thế nào cho ổn thỏa, đành phải dùng anti-pattern là Singleton để giải quyết vấn đề này.

Singleton là gì?

Dành cho các bạn chưa biết: Singleton là Design Pattern được thiết kế để hạn chế khởi tạo instance của Class về một object duy nhất. Tức là nó chỉ khởi tạo một lần và dùng lại cho toàn bộ hệ thống.

Nói một cách đơn giản hơn thì instance của Singleton giống như một “global object” vậy.

Anti-pattern là gì?

Khi một Design Pattern được dùng mang lại hại nhiều hơn lợi, gây ra nhiều hệ quả xấu như code thối, code khó test và khó bảo trì… thì nó là anti-pattern. Như đã nói ở trên, Singleton là một anti-pattern. Nói vậy không có nghĩa là hoàn toàn không nên dùng Singleton, tùy trường hợp các bạn ạ. Ví dụ như trường hợp  bạn phải chọn giữa việc dùng Singleton hoặc bị sút vào đít =))

Ví dụ về Singleton với JavaScript

Mục đích của tôi là để trao đổi giá trị giữa 2 modules, như vậy Singleton này chỉ cần khởi tạo một object rỗng là đủ:

let Singleton = (function () {
    let instance;

    function createInstance() {
        return Object(); // tạo object rỗng, có thể thay bằng Class khác
    }

    return {
        getInstance: function () {
            if (!instance) { // nếu chưa tồn tại thì tạo mới
                instance = createInstance();
            }
            return instance;
        }
    };
})();

Giờ ta gọi Singleton.getInstance(); ở bất kỳ đâu nó cũng chỉ trả về cùng một object mà thôi. Dựa vào đoạn mã trên, tôi tạo module singleton.js với nội dung như sau:

module.exports = function () {
    return Singleton.getInstance();
};

let Singleton = (function () {
    let instance;

    function createInstance() {
        return Object();
    }

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

Vậy là đã xong, giờ ví dụ tôi muốn trao đổi giá trị giữa hai module a và b trong đó module a được export trước. Ở module a:

let singleton = require('./singleton');
singleton().myName = 'Jared';

Ở module b:

let singleton = require('./singleton');
console.log(singleton()); // { myName: 'Jared' }
0 0 votes
Article Rating