Sunday, January 15, 2017

[Design Pattern] Singleton trong java và swift


Mẫu thiết kế singleton:
Nó là gì?
Mẫu thiết kế singleton đảm bảo chỉ duy nhất môt thực thể của một class được tạo ra và nó sẽ cung cấp cho bạn một phương thức để truy cập đến thực thế đó.
Kiểm soát việc tạo ra các thực thể nhưng có thể lấy ra thực thế.
Dùng nó trong trường hợp nào?
Khi bạn tạo ra một class mà bạn chỉ muốn chỉ có duy nhất một thực thể là thể hiện của class đó và bạn có thể truy cập đến nó ở bất kỳ nơi đâu khi bạn muốn.
Ví dụ như : Khi bạn tạo ra một class làm việc với file, config ,class lưu collection dùng chung, hoặc database . Bản chỉ cần duy nhất một thực thể của class đó và bạn sẽ sử dụng nó ở bất kỳ nơi đâu.
Dùng nó như thế nào?
Đầu tiên tôi tạo ra một class với tên là Database. Để không class nào có thể khỏi tạo nó (đảm bảo duy nhất có một thực thể) tôi sẽ private contructor của class trên.
  1. In Java
  2. public class Database{
  3.     private Database();
  4. }
  5. In Swift
  6. class Database{
  7.     private init();
  8. }
Và tạo một thuộc tính có tên là INSTANCE có kiểu Database  và một phương trả về thuộc tính đó. Để các class khác có thể sử dụng phương thức này, tôi thêm từ khóa static để biến phương thức này thành phương thức của lớp.
  1. In Java
  2. private Database INSTANCE;
  3. public static Database getInstance(){
  4.    if(INSTANCE == null){
  5.       INSTANCE = new Database();
  6.    }
  7.    return INSTANCE;
  8. }
  9. In Swift
  10. var Database sharedInstance;
  11. class func getInstance() -> Database { 
  12.    if(sharedInstance == nil) { 
  13.       sharedInstance = Database() 
  14.    } 
  15.    return sharedInstance 
  16. }
Như trên tôi kiểm tra xem INSTANCE có bằng null hay không. Nếu bằng null thì tôi tạo một đối tượng. Và trả về INSTANCE.
Có một vấn đề xảy ra. Nếu có hai luồng (thread) chạy song song và thực hiện hàm if thì sẽ có 2 thực thể được tạo ra. Để tránh trường hợp này mình thêm từ khóa synchronized. Khi hàm getInstance đã được chạy thì bất kỳ các luồng khác phải đợi hàm này chạy xong mới gọi được.

  1. public static synchronized Database getInstance(){
  2.    if(INSTANCE == null){
  3.      INSTANCE = new Database();
  4.    }
  5.    return INSTANCE;
  6. }
Ok đến đây đã khá ổn nhưng sử dụng từ khóa synchronized đồng nghĩa với việc các luồng có thể phải đợi chờ lâu vì phải đợi luồng đang gọi hạm getInstance chạy xong mới gọi được. Để tránh trường hợp này, tôi sẽ tạo 1 thực thể của lớp Database ngày khi class này được sử dụng, và sử dụng từ khóa final để ngăn không cho thay đổi đối tượng mà INSTANCE trỏ đến  :

  1. In Java:
  2. private static final Database INSTANCE = new Database();
  3. In Swift
  4. static let sharedInstance = Database()
Lúc này hàm getInstance sẽ trả về đối tượng INSTANCE:
  1. In Java:
  2. public static Database getInstance(){
  3.    return INSTANCE;
  4. }
  5. In Swift
  6. class func getInstance() -> Database { 
  7.    return sharedInstance 
  8. }
Để truy cập đến thực thể của class Database bạn thực hiện : Database.getInstance() lúc này trả về 1 thực thể có kiểu Database.
Với swift ta làm như sau:

OK ! Đến đây bạn có thể chắc chắn rằng sẽ chỉ có duy nhất một thực thể của class Database được tạo ra và bạn có thể sử dụng hàm getInstance để truy cập vào thực thế đó. Việc còn lại là bạn viết các phương thức, các setter, getter cho nó. Đây chính là mẫu thiết kế singleton.

4 comments:

  1. I learn some new stuff from it too, thanks for sharing your information.I thought I would leave my first comment. I don't know what to say except that I have enjoyed reading. best autoketing app, Discount master app, Product discount master

    ReplyDelete
  2. When I need a piece of advice, I will find your posts and read them..I love putting together useful information, this particular publish has got me personally a lot more info!
    autoketing.com shipping bar app Shopify free shipping bar app

    ReplyDelete

  3. play food games
    basketball online games
    soccer games online
    When I need a piece of advice, I will find your posts and read them..I love putting together useful information, this particular publish has got me personally a lot more info!

    ReplyDelete
  4. Hello, i think that i saw you visited my site thus i came to “return the favor”.I’m trying to find things to improve my web site!I suppose its ok to use a few of your ideas!!
    friv Games
    jogo io
    2player games

    ReplyDelete