AS3 và mẫu thiết kế Singleton

Bối cảnh bài viết

Trong một lần phỏng vấn với technical team của Playsoft, tôi được đặt khá nhiều câu hỏi về design pattern. Phần lớn các câu hỏi đó xoay quanh mẫu thiết kế Singleton. Tôi cũng đã từng làm việc với mẫu thiết kế này khá nhiều, đặc biệt là trong các project có hỗ trợ đa ngôn ngữ thì việc xây dựng một cơ chế quản lý ngôn ngữ thường xoay quanh mẩu thiết kế Singleton. Nhưng tôi cũng ít chú ý đến bản chất thật sự của nó cho đến khi có những câu hỏi xoay quanh mẫu thiết kế này. Vậy mẫu thiết kế Singleton là gì ?

Định nghĩa

Singleton là một mẫu thiết kế (design pattern) được sử dụng để bảo đảm mỗi một lớp (class) chỉ có được một thực thể (instance) duy nhất và mọi tương tác đều thông qua thực thể này.

Cài đặt và cách sử dụng

Với AS3, nếu bạn đã từng tham khảo qua pureMVC framework thì có thể thấy Facade của pureMVC là một Singleton. Theo quan điểm của riêng tôi thì các biến toàn cục (Global variables) – hoặc những tham chiếu toàn cục thường được cài đặt dựa theo mẫu Singleton.

Cài đặt một mẫu singleton phải đáp ứng một lớp chỉ có 1 instance duy nhất được tạo ra và instance này có thể được truy xuất ở phạm vi toàn cục. Có 2 cơ chế để xây dựng một mẫu singleton:

  • Cơ chế để truy cập các biến hoặc hàm của một lớp singleton mà không cần tạo một đối tượng lớp.
  • Cơ chế để đảm bảo sự thống nhất giữa các thành viên lớp và giữa các đối tượng lớp.

Các mẫu singleton cài đặt bằng cách tạo ra một lớp cùng với một phương thức sẽ trả về tham chiếu của đối tượng lớp nếu nó đã tồn tại hoặc sẽ tạo mới nếu nó chưa hề tồn tại.

Một vấn đề nữa cần lưu ý đó là với các ứng dụng đa nhiệm, nếu có đồng thời 2 thread cùng khởi tạo khi singleton chưa tồn tại thì cả 2 đều phải kiểm tra và chỉ 1 trong 2 thread này được khởi tạo singleton mà thôi.

Singleton và AS3

AS3 dựa trên ECMAScript vốn chưa hoàn thiện nên nó bắt buộc các class contructor phải khai báo ở phạm vi public – điều này khiến cho các lập trình viên khá lúng túng khi cài đặt theo mẫu Singleton, tuy nhiên chúng ta cũng có một số cách để cheat sự hạn chế này. Blog gskinner giới thiệu 2 cách để cài đặt singleton với AS3. Cách thứ nhất dùng cơ chế “quăng lỗi lúc chạy – throwing a run-time error” nếu bạn cố tình khởi tạo một instance của singleton trực tiếp. Nhược điểm của cách này là bạn sẽ chẳng biết được lỗi khi compile. Cách thứ 2 là khai báo các lớp private bên ngoài package và dùng nó như một “khóa – key” để điều khiển quá trình khởi tạo. Ngược lại với cách thứ nhất, cách này sẽ cho bạn biết các lỗi khi compile.

Xin được trích từ blog gskinner.com 2 cách cài đặt này

Cách 1:

// Singleton class:
package {

   public class SingletonDemo {
      private static var instance:SingletonDemo;
      private static var allowInstantiation:Boolean;

      public static function getInstance():SingletonDemo {
         if (instance == null) {
            allowInstantiation = true;
            instance = new SingletonDemo();
            allowInstantiation = false;
          }
         return instance;
       }

      public function SingletonDemo():void {
         if (!allowInstantiation) {
            throw new Error("Error: Instantiation failed: Use SingletonDemo.getInstance() instead of new.");
          }
       }
    }
}

Cách 2:

package {

   public class SingletonDemo {
      private static var instance:SingletonDemo;

      public static function getInstance():SingletonDemo {
         if (instance == null) {
            instance = new SingletonDemo(new SingletonBlocker());
          }
         return instance;
       }

      public function SingletonDemo(p_key:SingletonBlocker):void {
         // this shouldn't be necessary unless they fake out the compiler:
         if (p_key == null) {
            throw new Error("Error: Instantiation failed: Use SingletonDemo.getInstance() instead of new.");
          }
       }
    }
}
// the following code is also in the SingletonDemo.as file
// this class is only available to SingletonDemo
// (despite the internal access designation)
internal class SingletonBlocker {}

Tổng kết

Có thể mỗi lập trình viên sẽ có cách cài đặt khác nhau và phạm vi ứng dụng khác nhau dựa trên kinh nghiệm của mình. Bài viết này chỉ mang tính giới thiệu nên tôi cũng rất mong các comment chia sẽ về kinh nghiệm sữ dụng mẫu Singleton này.

Tham khảo:

Singleton pattern on Wikipedia [http://en.wikipedia.org/wiki/Singleton_pattern]

AS3: Singletons on gskinner.com [http://www.gskinner.com/blog/archives/2006/07/as3_singletons.html]

9 thoughts on “AS3 và mẫu thiết kế Singleton

  1. Bạn ơi!
    Cho hỏi, getInstance(): Type{}

    Type đó có thể là một Generic được không bạn. Lúc trước tôi viết Singleton trên C# và tui chỉ viết một Class mà muốn dùng cho tất cả các đối tượng. Code như thế này:

    ——————————————————–
    using System.Text;
    using System.Windows.Forms;

    namespace AWA.Presentation
    {
    public sealed class SingletonForm where T: Form, new()
    {
    private static T instance = default(T);
    private static readonly object padlock = new object();
    private SingletonForm() { }

    public static T Instance
    {
    get
    {
    lock (padlock)
    {
    if (instance == null || instance.IsDisposed)
    {
    instance = new T();
    }
    return instance;
    }
    }
    }
    }
    }
    ———————————————————-

    Sử dụng:

    SingletonForm.Instance.Show();

    ———————————————————-

    Không biết làm như thế có vi phạm khái niệm Singleton ko, mong chỉ giáo.

    Thanks rất nhiều!

  2. Sorry, cách sử dụng, tôi viết thiếu!

    Bổ sung, cách sử dụng:

    SingletonForm.Instance.Show();

  3. Không hỗ trợ nhập ký tự lớn nhỏ rồi

    SingletonForm(Type).Instance.Show();

    Chú thích:
    ( = dấu nhỏ
    ) = dấu lớn

  4. Chào nguyenlamzx
    Trước hết, một lớp được cài đặt theo mẫu Singleton là một lớp chỉ có thể tạo được một instance duy nhất. Nếu thỏa mãn điều kiện này nghĩa là bạn đã có 1 Singleton. Còn việc bạn dùng như thế nào, trong lớp đó implement các hàm nào thì hoàn toàn do bạn quyết định. Mình không làm về .NET nhưng theo mình biết Generic là 1 tính năng của .NET 2.0 cho phép chúng ta định kiểu an toàn. Có thể bạn đang hiểu là Type ở đây phải là Type của Class Singleton nhưng Singleton không ràng buộc điều mà bạn đang thắc mắc.

    Theo ngữ cảnh mà bạn cài đặt SingletonForm, tôi đoán là bạn đang xây dựng một DialogBox giống như Find Dialog trong các ứng dụng Word, Excel … Thực tế thì các ứng dụng này đang áp dụng Singleton Pattern cho hộp thoại dạng Find Dialog, Search And Replace … v.v..

    Còn cách sử dụng bạn đưa ra thì hoàn toàn đúng vì đó là cách để truy xuất instance của Singleton.

  5. Có gì mong bạn chỉ giáo AS3 he! Tôi cũng rất hứng thù làm AS3 và Flex. Nhưng chưa được nghiên cứu chuyên sâu.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s