2012-07-02 16 views

Trả lời

47

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.

+2

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

+0

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 –

21

Ý 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.

+0

Tôi nghĩ rằng chỉ làm cho [giải thích] SRP đáng ngờ. –

+0

Theo cách nào đáng ngờ? – MikePatel

+0

Đá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. –

6

Có rất nhiều yêu cầu mà bạn có thể có trên các singleton:

  1. lười biếng khởi;
  2. xử lý thích hợp; Ví dụ:
  3. 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ó.

7

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.

10

[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.

+2

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 đó? –

+2

@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. –

+0

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ó. –

3

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.

Các vấn đề liên quan