Tôi đã thấy một số người trong SO bình luận rằng Singleton Pattern là một mẫu chống. Tôi muốn biết tại sao ?Tại sao việc triển khai mẫu Singleton trong mã Java là (đôi khi) được coi là một mẫu chống trong thế giới Java?
Trả lời
Testing
Một lý do là độc thân không phải là dễ dàng để xử lý với đơn vị xét nghiệm. Bạn không thể kiểm soát sự khởi tạo và bởi chính bản chất của chúng có thể giữ trạng thái trên các lời gọi.
Vì lý do đó, nguyên tắc dependency injection là phổ biến. Mỗi lớp được tiêm (được cấu hình) với các lớp mà chúng cần để hoạt động (thay vì lấy được thông qua các trình truy cập đơn) và vì vậy các kiểm tra có thể kiểm soát các cá thể lớp phụ thuộc nào để sử dụng (và cung cấp mocks nếu được yêu cầu).
Các khung như Spring sẽ điều khiển vòng đời của các đối tượng của chúng và thường tạo ra các bộ đơn, nhưng các đối tượng này được tiêm vào các đối tượng phụ thuộc của chúng bằng khung công tác. Vì vậy, codebase chính nó không đối xử với các đối tượng như singletons.
ví dụ: chứ không phải này (ví dụ)
public class Portfolio {
private Calculator calc = Calculator.getCalculator();
}
bạn sẽ bơm máy tính:
public class Portfolio {
public Portfolio(Calculator c) {
this.calc = c;
}
}
Do đó, đối tượng Portfolio
không biết/quan tâm đến bao nhiêu trường hợp của Calculator
tồn tại. Các xét nghiệm có thể tiêm một dummy Calculator
giúp việc kiểm tra trở nên dễ dàng.
Concurrency
Bằng cách giới hạn mình vào một thể hiện của một đối tượng, các tùy chọn cho luồng còn hạn chế. Truy cập vào đối tượng đơn lẻ có thể phải được bảo vệ (ví dụ: thông qua đồng bộ hóa). Nếu bạn có thể duy trì nhiều trường hợp của các đối tượng đó, thì bạn có thể điều chỉnh số lượng phiên bản cho các chủ đề bạn đang chạy và tăng khả năng đồng thời của codebase của bạn.
Vì vậy, làm thế nào để những người sử dụng đơn lẻ đối phó với "Thử nghiệm" và " Vấn đề "đồng thời"? – Pacerier
Với một số khó khăn. Các công cụ như PowerMock có thể cung cấp phương tiện ghi đè các phương thức singleton, nhưng chúng là các công cụ phức tạp dùng để thao tác bytecode –
Ý kiến cá nhân của tôi là nó vi phạm nguyên tắc trách nhiệm duy nhất. Các đối tượng Singleton chịu trách nhiệm cho cả mục đích của chúng và kiểm soát số lượng các trường hợp chúng tạo ra mà tôi nghĩ là sai.
Đây là lý do tại sao nhiều người ủy quyền kiểm soát đối tượng nhà máy.
Tôi nghĩ rằng chỉ làm cho [giải thích] SRP đáng ngờ. –
Theo cách nào đáng ngờ? – MikePatel
Đáng ngờ trong điều này rõ ràng không phải là một điều sai với Singletons, nhưng việc giải thích SRP chỉ ra rằng nó là. SRP (hay cách giải thích của nó) có vẻ như là một bên có tội. –
Có rất nhiều yêu cầu mà bạn có thể có trên các singleton:
- lười biếng khởi;
- xử lý thích hợp; Ví dụ:
- phạm vi (ví dụ: một chủ đề).
Thông thường, ngoài ra, bạn sẽ có rất nhiều đơn trong ứng dụng của mình và mẫu Singleton không cho phép sử dụng lại mã. Vì vậy, nếu bạn muốn thực hiện tất cả những mối quan tâm này cho tất cả các người độc thân của mình, bạn sẽ ngay lập tức thấy chất lượng chống chống mẫu của nó.
Những người độc thân như vậy không nhất thiết phải chống mẫu, nhưng họ chỉ có ít lợi ích và trở thành một mẫu giả khi chúng được sử dụng sai (thường xảy ra).
Thông thường, người độc thân không phải là người độc thân, mà là "biến toàn cục trong ngụy trang". Ngoài ra, thường chúng được sử dụng khi thuộc tính "chỉ một thể hiện" thực sự không phải là một lợi thế. (mà một lần nữa được cân bằng bởi thực tế là nhiều lần thực hiện là sai cùng một lúc). Ngoài ra, họ có thể khó khăn để thực hiện với đa luồng trong tâm trí (thường được thực hiện sai hoặc không hiệu quả), và họ mất hầu hết các lợi ích của họ nếu bạn muốn kiểm soát instantiation của họ.
Nếu bạn muốn kiểm soát việc khởi tạo, bạn cần thực hiện bằng tay tại một số điểm trong chương trình, nhưng sau đó bạn cũng có thể tạo một thể hiện của đối tượng bình thường và chuyển nó trở đi.
Nếu thứ tự hủy diệt là bất kỳ mối quan ngại nào, bạn cũng cần thực hiện thủ công điều này. Một đối tượng tự động duy nhất trong chức năng chính chỉ đơn giản hơn rất nhiều và dễ dàng hơn.
[Mutable] Singleton là mô hình chống mẫu.
Mẫu quan trọng cơ bản chống là trạng thái toàn cầu (hoặc trạng thái môi trường xung quanh). Với tình trạng toàn cầu, bạn có một blog lớn về sự phụ thuộc trong chương trình của bạn. Điều này không ảnh hưởng đến thử nghiệm, nhưng đó chỉ là một phần của sự thiếu hụt từ chương trình xấu.
Được xếp vào lớp đó, Singleton thêm mức độ phức tạp không cần thiết hoàn toàn chỉ đơn giản là tuyên bố các trường có thể biến đổi static
.
các trường bị cùng một vấn đề chính xác, đó là trạng thái toàn cục. Tôi không thấy cách sử dụng các trường tĩnh là tốt hơn so với một singleton. Mọi thông tin về điều đó? –
@JuanMendes Như tôi đã nói, các thống kê có thể thay đổi đơn giản tốt hơn so với các thống kê có thể thay đổi được bởi vì chúng không có sự phức tạp vô nghĩa. –
Tôi nên xem lại câu trả lời tốt hơn trước khi để lại nhận xét. 100% đồng ý với bạn. Về cơ bản nó là một chủ nghĩa euphem cho tình trạng toàn cầu, vì vậy gọi nó là các lĩnh vực tĩnh ít nhất không cố gắng tôn tạo nó. –
Lạ. Có vẻ như việc thực hiện không chính xác Singleton là một "mô hình chống", không phải bản thân Singleton.
Tôi nghĩ chúng tôi đã quên rằng mọi chương trình đều phải bắt đầu từ đâu đó. Phải có một sự thực thi cụ thể về mọi trừu tượng, và cuối cùng mọi phụ thuộc cuối cùng sẽ được giải quyết, hoặc ứng dụng của bạn sẽ không được sử dụng nhiều.
Hầu hết các khung công tác DI cho phép tạo lớp học dưới dạng Singleton, nó chỉ xử lý cho bạn. Nếu bạn chọn làm DI mình, tiêm một singleton không phải là một vấn đề. Một Singleton IS có thể kiểm tra là tốt, và nếu bạn đang sử dụng DI để tiêm nó, không làm cho một lớp học không ổn định.
IMO, giống như mọi mẫu khác ngoài đó (bao gồm DI và IoC), đó là một công cụ. Đôi khi nó phù hợp, đôi khi nó không.
- 1. Tại sao "siêu gọi" được coi là một mẫu chống theo Wikipedia?
- 2. Tại sao mảng Java này được coi là hai chiều?
- 3. Tại sao mẫu Borg tốt hơn mẫu Singleton trong Python
- 4. Triển khai gốc trong Java là gì?
- 5. Tránh phơi bày chi tiết triển khai khi triển khai mẫu quan sát trong Java?
- 6. Triển khai mẫu Sự kiện miền trong Java?
- 7. tại sao hằng số java được khai báo là tĩnh?
- 8. Thư viện Java HTML (chống mẫu)?
- 9. Java Tại sao chuyển đổi dài (64) thành float (32) được coi là mở rộng?
- 10. Là '.' để truy cập thành viên được coi là một toán tử trong Java?
- 11. Tại sao phát hiện đường dẫn A * đôi khi đi theo đường thẳng và đôi khi là đường chéo? (Java)
- 12. Tại sao Redis được coi là CP?
- 13. Tên của mẫu chống này là gì?
- 14. mẫu HTTP sao chổi trong Java
- 15. Các mảng được triển khai trong java như thế nào?
- 16. Tại sao viết vào clipboard trong JS được coi là một lỗ hổng bảo mật?
- 17. Triển khai mẫu Phương thức mẫu trong C#
- 18. Tại sao không hiển thị được coi là một chuyển đổi trong haskell?
- 19. Tại sao việc triển khai và khai báo một lớp mẫu phải nằm trong cùng một tệp tiêu đề?
- 20. Các ứng dụng Java được triển khai như thế nào trong "thế giới thực"?
- 21. Tại sao khai báo một đối số hàm để là kết quả cuối cùng?
- 22. Tại sao phương thức giao diện C# được triển khai trong một lớp là công khai?
- 23. Kiểm tra xem một đôi là vô hạn trong Java
- 24. Cách siêu được triển khai trong Java?
- 25. Điều gì được coi là thực hành tốt cho việc viết mã trong các tình huống "thế giới thực"?
- 26. Mẫu Singleton trong C++
- 27. Tại sao mã này được coi là O (N^6) trong ký hiệu Big Oh?
- 28. JavaPOS Xin chào thế giới trong Java
- 29. Triển khai OAuth trong Java
- 30. Mixin có được coi là mẫu thiết kế không?
bản sao có thể có của [Singleton Design Pattern: Pitfalls] (http://stackoverflow.com/questions/1448393/singleton-design-pattern-pitfalls) – msw