2009-10-26 20 views

Trả lời

13

Đã trả lời cho một câu hỏi tương tự cách đây vài ngày here, mocking a Singleton. Bài viết gốc là dành cho C# .Net liên quan đến việc chế nhạo hành vi của một singleton, nhưng vẫn nên áp dụng.

Về mẫu đơn, không có gì sai với nó - trong nhiều trường hợp, chúng tôi muốn tập trung logic và dữ liệu. Tuy nhiên, có một sự khác biệt rất lớn giữa một singleton và một lớp tĩnh. Xây dựng singleton của bạn như là một mã lớp cứng tĩnh mà thực hiện cho mọi người tiêu dùng trong ứng dụng của bạn - điều này làm cho việc kiểm tra đơn vị rất khó khăn!

Điều bạn muốn làm là xác định giao diện cho singleton của bạn, phơi bày các phương pháp để người tiêu dùng sử dụng. Người tiêu dùng của bạn lần lượt là thông qua tham chiếu đến lớp triển khai bởi bất kỳ ai khởi tạo chúng [thường đây là ứng dụng của bạn hoặc vùng chứa nếu bạn quen với Dependency Injection \ Inversion of Control].

Đó là khuôn khổ này, bất kỳ ai đang khởi tạo người tiêu dùng, chịu trách nhiệm đảm bảo một và chỉ một cá thể đang trôi nổi xung quanh. Nó thực sự không phải là một bước nhảy vọt từ lớp tĩnh đến tham chiếu giao diện [như được minh họa trong liên kết ở trên], bạn chỉ mất đi sự tiện lợi của một cá thể truy cập toàn cầu - tôi biết tôi biết, tham chiếu toàn cầu cực kỳ quyến rũ, nhưng Luke quay lưng lại với Dark Side, bạn cũng vậy!

Nói chung, các phương pháp hay nhất đề xuất tránh tham chiếu tĩnh và khuyến khích tích hợp các giao diện. Hãy nhớ rằng, vẫn có thể áp dụng mẫu đơn với những ràng buộc này. Thực hiện theo các nguyên tắc này và bạn sẽ không gặp phải vấn đề gì khi kiểm tra công việc của mình :)

Hy vọng điều này sẽ hữu ích!


singleton! = Public static class, thay singleton == single dụ

1

I'm using the following pattern khi tôi viết một độc thân tĩnh dựa trên mà tôi có thể chế nhạo. Mã này là Java, nhưng tôi nghĩ bạn sẽ có một ý tưởng. Vấn đề chính với cách tiếp cận này là bạn phải thư giãn constructor để gói bảo vệ (mà sorta đánh bại một singleton đúng). Là một lưu ý phụ - mã áp dụng cho khả năng giả lập mã "tĩnh" của bạn không nhất thiết phải gọi nó là

3

Thiếu khả năng kiểm thử là một trong những nhược điểm chính của mô hình Singleton cổ điển (phương thức tĩnh trả về một thể hiện). Theo như tôi đang quan tâm, đó là biện minh đủ để thiết kế lại bất kỳ mã nào sử dụng Singletons để sử dụng một số thiết kế khác.

Nếu bạn hoàn toàn cần phải có một ví dụ đơn lẻ, thì Dependency Injection và ghi vào một giao diện, theo gợi ý của johnny g, chắc chắn là con đường để đi.

0

Nếu bạn phải sử dụng một singleton (và có nhiều lý do để làm như vậy ... nhưng tôi sẽ luôn luôn cố gắng tránh nó nếu có thể). Tôi khuyên bạn nên sử dụng một container IOC để quản lý nó. Im không chắc chắn nếu có một cho Delphi hay không. Nhưng trong Java bạn có thể sử dụng Spring, trong .NET bạn có thể sử dụng Windsor/Castle. Một container IOC có thể chứa trên Singleton và có thể đăng ký các cài đặt khác nhau để thử nghiệm.

Nó có lẽ là quá lớn của một chủ đề để có được vào đây ngoài đoạn này.

1

Tôi thường chỉ sử dụng Singletons cho đối tượng Flyweight hoặc các đối tượng có giá trị tương tự. Nhìn vào một container IoC (như đã thảo luận ở trên) có lẽ là một cách tốt hơn để xử lý một đối tượng được chia sẻ hơn một singleton.

Hãy xem xét rằng trong Smalltalk (nơi rất nhiều các mẫu có nguồn gốc), đúng và sai đều có hiệu quả độc thân :)

+0

... về Smalltalk: yes, nhưng đúng và sai là kiểm chứng _so_ :) – mjn

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