Bạn đã bao giờ muốn tạo một lớp chỉ có thể có một phiên bản?
Đúng? Không? Có thể?
Chà…
Đó chính xác là những gì mô hình singleton là.
Không có vấn đề gì với điều đó.
Nhưng một số người gọi điều này là phản mẫu vì nó có thể được sử dụng như một cái cớ cho thiết kế xấu.
Hãy xem ví dụ về mã để bạn có thể tìm hiểu cách hoạt động của nó.
Ví dụ về mã mẫu Singleton
Ý tưởng của mô hình singleton là bạn muốn một lớp chỉ có một thể hiện.
Đây là cách thực hiện :
- Bạn tạo
new
phương pháp riêng tư - Bạn xác định một phương thức lớp có tên là
instance
trả về cá thể duy nhất cho lớp
Bởi vì đây là một mẫu thiết kế phổ biến, thư viện chuẩn của Ruby đi kèm với một Singleton
mô-đun bạn có thể đưa vào bất kỳ lớp nào.
Có vẻ như thế này :
require 'singleton' class Shop include Singleton end
Bây giờ nếu bạn cố gắng tạo một Shop
đối tượng với Shop.new
bạn sẽ thấy điều này:
Shop.new # NoMethodError: private method `new' called for Shop:Class
Và nếu bạn muốn có một &duy nhất Shop
đối tượng bạn có thể sử dụng instance
phương pháp:
Shop.instance.object_id # 5659218 Shop.instance.object_id # 5659218
Bạn có thể biết nó luôn là cùng một đối tượng vì object_id
không bao giờ thay đổi.
Điều bạn cần nhớ :
Đây là một mẫu đơn giản, nó giới hạn việc tạo đối tượng ở 1 đối tượng và bạn có thể yêu cầu đối tượng đó bất cứ khi nào bạn muốn.
Tại sao bạn không nên sử dụng mẫu này
Mô hình singleton thường là cái cớ để có một số dạng biến toàn cục và chúng tôi biết rằng các biến toàn cục là không tốt vì bạn không có quyền kiểm soát chúng. Điều này làm cho mọi thứ khó kiểm tra hơn và nó có thể làm tăng khả năng ghép nối.
“Vấn đề thực sự với Singletons là họ cho bạn một lý do chính đáng như vậy để không suy nghĩ kỹ về khả năng hiển thị thích hợp của một đối tượng.” - Kent Beck
Hãy tưởng tượng có một đối tượng mà hầu hết các lớp của bạn phụ thuộc vào, đó là những gì mà mẫu singleton có thể trở thành. Chúc may mắn khi cấu trúc lại!
Bây giờ :
Có bất kỳ công dụng tốt nào cho mẫu này không?
Tìm kiếm trên Github đã tìm ra một số repo bằng cách sử dụng mẫu Singleton kết hợp với mẫu đối tượng Null.
Tôi đoán điều đó có lý, Rails sử dụng điều này như một phần của ActionPack.
Đây là mã :
class AllType < Type include Singleton def initialize super "*/*", :all end def all?; true; end def html?; true; end end
Đây là lớp kế thừa từ Type
.
Khi bạn tạo một AllType
đối tượng thông qua instance
, nó sẽ gọi super &trả về đối tượng.
Mỗi khi bạn gọi instance
sau đó, bạn sẽ nhận được cùng một đối tượng.
Kết luận :
Có, mẫu này có thể hữu ích trong những trường hợp thích hợp, nhưng bạn không muốn sử dụng nó mà không cần suy nghĩ nhiều về nó.
Video
Tóm tắt
Bạn đã tìm hiểu về mẫu thiết kế singleton, cách triển khai nó trong Ruby và tại sao bạn nên tránh nó hầu hết thời gian.
Bạn nghĩ gì về mô hình này? Bạn đã thấy nó bao giờ chưa? Hãy cho tôi biết trong phần bình luận 🙂
Cảm ơn vì đã đọc!