JavaScript Design Pattern - Singleton Pattern

Có thể bạn đã nghe quen về Singleton. Singleton Pattern giới hạn số lượng instance của một class là một. Trong JavaScript, bạn có thể triển khai Singleton Pattern theo cách sau.

Singleton Pattern cơ bản

var mySingleton = (function() {
  var instance;
  function init() {
    var number = 0;
    return {
      setNumber : function(x) {
        number = x;
      },
      getNumber : function() {
        return number;
      }
    };
  }

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

var instA = mySingleton.getInstance();
console.log("instance A: ", instA.getNumber()); // instance A: 0
instA.setNumber(10);
console.log("instance A: ", instA.getNumber()); // instance A: 10

var instB = mySingleton.getInstance();
console.log("instance B: ", instB.getNumber()); // instance B: 10

console.log(instA === instB);                   // true

Giải thích

Các bạn có thể thấy, cách triển khai Singleton trên rất giống với Module Pattern. Chỉ có một chú ý là, mySingleton chỉ có một access point duy nhất là getInstance. Vậy tại sao khi sử dụng function này thì ta chỉ thu được một instance duy nhất?

Đúng vậy, ban đầu khi chưa gọi getInstance lần nào thì biến instance sẽ là undefined. Lúc này, instance sẽ được khởi tạo bằng cách sử dụng hàm số init. Cuối cùng, hàm số trả về biến instance. Đối với các lần gọi getInstance tiếp theo, vì instance đã khác undefined nên nó sẽ không được tạo mới mà sẽ return ngay lập tức.

Như ví dụ trên, instA khi mới tạo ra thì getNumber sẽ trả về 0. Trong khi, instB khi mới tạo ra thì getNumber trả về 10 - giá trị này được set ở instA trước đó. Và quan trọng hơn, instA === instB trả về giá trị true. Như vậy, thực chất instB cũng chính là instA.

Singleton with a cached static property

function User() {  
  // do we have an existing instance?
  if (typeof User.instance === 'object') {
      return User.instance;
  }

  // proceed as normal
  this.firstName = 'John';
  this.lastName = 'Doe';

  // cache
  User.instance = this;

  // implicit return
  // return this;
}

// Usage:
var curUser = new User();
console.log(curUser.firstName, curUser.lastName); // John Doe

var other = new User();
console.log(other.firstName, other.lastName);     // John Doe
console.log(other === curUser);                   // true

Cách này khi mới đọc thì sẽ thấy hơi ảo, ở chỗ là, trong hàm User ta lại sử dụng User.instance. Nhưng nếu nhìn theo khía cạnh, function cũng chính là một object thì mọi chuyện sẽ trở nên đơn giản.

Như trong ví dụ trên, khi khởi tạo curUser (lần đầu tiên), User.instance đang có giá trị là undefined, nên mọi thứ được xử lý như bình thường. Khi kết thúc hàm, ta gán User.instance = this hay nói cách khác là User.instance = curUser. Đến khi khởi tạo đối tượng thứ hai là other, lúc này User.instance đã là curUser - một object, nên hàm trên sẽ return về User.instance (curUser). Đó, dù có gọi hàm khởi tạo bao nhiêu lần thì ta cũng chỉ thu được một đối tượng duy nhất.

Tham khảo


Theo dõi Lam Pham trên Kipalog để nhận thông báo khi có bài viết mới nhất:

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Lam Pham

23 bài viết.
40 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
24 10
Trước khi vào nội dung bài viết. Tôi xin đính chính giúp anh trả lời những câu hỏi chỉ là tựa đề của một bài hát tôi không có ý xưng hô là anh. Bài...
Lam Pham viết 6 tháng trước
24 10
White
13 6
Có thể bạn thừa biết, JavaScript là một ngôn ngữ chạy (Link). Điều đó có nghĩa là nếu bạn thực hiện một tác vụ quá lớn trên giao diện chính thì khả...
Lam Pham viết 6 tháng trước
13 6
White
13 2
Xin chào bạn Có thể bạn đã biết, JavaScript là một ngôn ngữ lập trình rất mạnh, nhưng lại vô cùng rắc rối, phức tạp. Để có thể nắm vững được Java...
Lam Pham viết 2 tháng trước
13 2
Bài viết liên quan
White
1 0
Đối với (Link), cách đơn giản nhất để tạo mới một object là sử dụng function kết hợp với từ khoá new. Bên trong hàm khởi tạo này, từ khoá this dùng...
Lam Pham viết 5 tháng trước
1 0
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
23 bài viết.
40 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!