Trong công nghiệp phần mềm, mô hình Singleton là một mẫu thiết kế phần mềm để hạn chế sự khởi tạo của lớp đối tượng. Điều này rất hữu ích khi cần một đối tượng chính xác để điều phối hành động trên toàn hệ thống. Khái niệm đôi khi được khái quát hóa cho các hệ thống vận hành hiệu quả hơn khi chỉ có một đối tượng tồn tại hoặc hạn chế sự khởi tạo cho một số lượng đối tượng nhất định. Thuật ngữ này xuất phát từ khái niệm toán học của một singleton.

Có một số người chỉ trích mô hình Singleton và xem nó là một mô hình chống lại hướng đối tượng bởi vì nó thường được sử dụng trong các kịch bản mà nó không có lợi, ví dụ như các hạn chế không cần thiết trong tình huống mà một trường hợp duy nhất của một class không thực sự cần thiết, Và đưa ra đối tượng chung vào một ứng dụng. Mẫu thiết kế Singleton [4] là một trong 23 mô hình thiết kế GoF nổi tiếng mô tả cách giải quyết các vấn đề thiết kế lặp lại để thiết kế linh hoạt và phần mềm hướng đối tượng dùng lại được, tức là các đối tượng dễ triển khai, thay đổi, Thử nghiệm và sử dụng lại.

Các mô hình Singleton thiết kế giải quyết vấn đề như: [5] sửa

Làm thế nào có thể được đảm bảo rằng một class chỉ có một đối tượng?

Làm thế nào có thể truy cập dễ dàng một thể hiện duy nhất của một class ?

Làm thế nào để một lớp kiểm soát sự hiện thân của nó?

Làm thế nào có thể hạn chế số lượng các thể hiện (instance) của một class?

Mẫu thiết kế Singleton mô tả cách giải quyết những vấn đề như: sửa

Ẩn constructor của lớp.

Xác định một hoạt động tĩnh công cộng (getInstance ()) trả về trường hợp duy nhất của lớp.

Ý tưởng chính trong mô hình này là làm cho lớp đó chịu trách nhiệm kiểm soát sự khởi tạo của nó (nó chỉ được khởi tạo một lần).

Các constructor ẩn đảm bảo rằng các singleton class không bao giờ có thể được instantiated từ bên ngoài.

Thao tác static có thể được truy cập dễ dàng bằng cách sử dụng tên lớp và tên method (Singleton.getInstance ()).

Sử dụng chung sửa

abstract factory, builder, và prototype patterns có thể sử dụng Singletons trong quá trình thực hiện.

Facade  thường sử dụng singleton.

Singleton thường được dùng quản lý biến toàn cục.

Singleton thường được ưa thích hơn các biến số toàn cục bởi vì:

  • Loại bỏ các biến ko cần thiết, chỉ quản lý các biến ứng dụng cần dùng tới.
  • Singleton sẻ chỉ sử dụng một số ít tài nguyên, còn biến toàn cục thì thường được tạo từ nhều ngôn ngữ / kiểu dữ liệu phức tạp nên tiêu tốn tài nguyên hơn.
Nơi để sử dụng nó sửa

Khi chỉ cho phép một trường hợp hoặc một số trường hợp cụ thể của một lớp. Các đối tượng Facade thường là những Singleton bởi vì ứng dụng luôn chỉ cần một đối tượng Facade.

Thực hiện sửa

Việc thực hiện mô hình Singleton phải:

Đảm bảo rằng chỉ có một instance của lớp Singleton tồn tại;

Cung cấp truy cập public cho trường hợp đó.

Thông thường, điều này được thực hiện bằng cách:

Tuyên bố tất cả các constructor của lớp phải là private

Cung cấp một phương thức tĩnh mà trả về một tham chiếu đến đối tượng.

Cá thể thường được lưu trữ dưới dạng một biến tĩnh riêng; Object được tạo ra khi biến được khởi tạo, tại một số điểm trước khi phương pháp tĩnh được gọi lần đầu tiên. Sau đây là một ví dụ được viết bằng Java.

public final class Singleton {
    private static final Singleton INSTANCE = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {
        return INSTANCE;
    }
}

Lazy initialization Một singleton thực hiện có thể sử dụng khởi tạo đa luồng, nơi dụ được tạo ra khi phương pháp tĩnh được gọi lần đầu tiên. Nếu phương pháp tĩnh có thể được gọi từ nhiều luồng đồng thời, cần phải có các biện pháp để ngăn ngừa các điều kiện có thể dẫn đến việc tạo ra nhiều trường hợp của lớp. Sau đây là một mẫu thực hiện an toàn, sử dụng khởi tạo chắc chắn với khóa kiểm tra kép, được viết bằng Java:

public final class Singleton {
    private static volatile Singleton instance = null;

    private Singleton() {}

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized(Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

Tham khảo sửa