Tôi đã đọc những ý kiến khác nhau về mẫu singleton. Một số duy trì rằng nó nên được tránh bằng mọi giá và những người khác rằng nó có thể hữu ích trong một số tình huống.
Một tình huống trong đó tôi sử dụng singletons là khi tôi cần một nhà máy (giả sử một đối tượng f thuộc loại F) để tạo các đối tượng của một lớp nhất định A. Nhà máy được tạo một lần bằng cách sử dụng một số tham số cấu hình và sau đó được sử dụng mỗi lần một đối tượng loại A được khởi tạo. Vì vậy, mọi phần của mã muốn khởi tạo A tìm nạp singleton f và tạo cá thể mới, ví dụ:
F& f = F::instance();
boost::shared_ptr<A> a = f.createA();
Vì vậy, kịch bản chung của tôi là
- Tôi chỉ cần một phiên bản của một lớp vì lý do tối ưu hóa (tôi không cần nhiều đối tượng nhà máy) hoặc để chia sẻ trạng thái chung (ví dụ: nhà máy biết có bao nhiêu phiên bản A mà nó vẫn có thể tạo)
- Tôi cần một cách để có quyền truy cập vào ví dụ này của F ở những nơi khác nhau của mã.
Tôi không quan tâm đến cuộc thảo luận liệu mẫu này là tốt hay xấu, nhưng giả sử tôi muốn tránh sử dụng một singleton, tôi có thể sử dụng mẫu nào khác?
Các ý tưởng tôi đã có (1) để lấy đối tượng nhà máy từ sổ đăng ký hoặc (2) để tạo nhà máy tại một số thời điểm trong quá trình khởi động chương trình và sau đó chuyển nhà máy xung quanh làm tham số.
Trong giải pháp (1), bản thân sổ đăng ký là một đơn, vì vậy tôi vừa chuyển vấn đề không sử dụng một đơn vị từ nhà máy sang cơ quan đăng ký.
Trong trường hợp (2) Tôi cần một số nguồn (đối tượng) ban đầu mà từ đó đối tượng nhà máy xuất hiện vì vậy tôi sợ rằng tôi sẽ lại rơi vào một singleton khác (đối tượng cung cấp thể hiện nhà máy của tôi). Bằng cách theo dõi lại chuỗi singletons này, tôi có thể giảm vấn đề thành một singleton (toàn bộ ứng dụng) mà tất cả các singleton khác được quản lý trực tiếp hoặc gián tiếp.
Liệu tùy chọn cuối cùng này (sử dụng một singleton ban đầu tạo ra tất cả các đối tượng duy nhất khác và tiêm tất cả các singleton khác vào đúng chỗ) có phải là một giải pháp chấp nhận được không? Đây có phải là giải pháp được đề xuất ngầm khi một người khuyên không nên sử dụng singletons, hoặc các giải pháp khác, ví dụ như trong ví dụ minh họa ở trên là gì?
CHỈNH SỬA
Vì tôi nghĩ rằng điểm của câu hỏi của tôi đã bị một số người hiểu lầm, đây là một số thông tin. Như đã giải thích ví dụ ở đây , từ singleton có thể chỉ ra (a) một lớp với một đối tượng cá thể và (b) một mẫu thiết kế được sử dụng để tạo và truy cập một đối tượng như vậy.
Để làm cho mọi thứ rõ ràng hơn, chúng ta hãy sử dụng thuật ngữ đối tượng duy nhất cho (a) và mẫu đơn cho (b). Vì vậy, tôi biết mô hình singleton và tiêm phụ thuộc là gì (BTW, gần đây tôi đã sử dụng DI rất nhiều để loại bỏ các trường hợp của mẫu singleton khỏi một số mã tôi đang làm việc).
Quan điểm của tôi là trừ khi toàn bộ biểu đồ đối tượng được khởi tạo từ một đối tượng duy nhất sống trên ngăn xếp của phương thức chính, sẽ luôn có nhu cầu truy cập một số đối tượng duy nhất thông qua mẫu singleton.
Câu hỏi của tôi là liệu việc tạo và kết nối đồ thị đối tượng hoàn chỉnh có phụ thuộc vào phương thức chính hay không (ví dụ thông qua một khung DI mạnh mẽ không sử dụng chính mẫu đó) là giải pháp miễn phí duy nhất cho mẫu đơn .