Service Locator chỉ là một trong hai tệ nạn để nói. "Ít hơn" sôi lên với bốn sự khác biệt này ( ít nhất tôi không thể nghĩ về bất kỳ khác ngay bây giờ ):
Nguyên tắc trách nhiệm đơn lẻ
Vùng chứa dịch vụ không vi phạm Nguyên tắc trách nhiệm đơn lẻ như Singleton làm. Singletons kết hợp việc tạo đối tượng và logic nghiệp vụ, trong khi Vùng chứa dịch vụ chịu trách nhiệm quản lý nghiêm ngặt các vòng đời đối tượng trong ứng dụng của bạn. Về mặt đó Service Container tốt hơn.
Khớp nối
Singleton thường được mã hóa cứng vào ứng dụng của bạn do các lệnh gọi phương thức tĩnh, dẫn đến các phụ thuộc được ghép nối chặt chẽ và khó bắt chước trong mã của bạn. Mặt khác SL chỉ là một lớp và nó có thể được tiêm vào. Vì vậy, mặc dù tất cả những gì được phân loại của bạn sẽ phụ thuộc vào nó, nhưng ít nhất nó là sự phụ thuộc được kết hợp lỏng lẻo. Vì vậy, trừ khi bạn triển khai ServiceLocator như một Singleton, điều đó có phần tốt hơn và cũng dễ kiểm tra hơn.
Tuy nhiên, tất cả các lớp sử dụng ServiceLocator bây giờ sẽ phụ thuộc vào ServiceLocator, đây cũng là một dạng kết hợp. Điều này có thể được giảm thiểu bằng cách sử dụng một giao diện cho ServiceLocator, do đó bạn không bị ràng buộc với việc triển khai ServiceLocator cụ thể nhưng các lớp của bạn sẽ phụ thuộc vào sự tồn tại của một số loại Locator trong khi việc không sử dụng ServiceLocator sẽ làm tăng việc tái sử dụng đáng kể.
Phụ thuộc ẩn
Mặc dù vậy, vấn đề ẩn các phụ thuộc vẫn tồn tại rất nhiều. Khi bạn chỉ đưa bộ định vị vào các lớp tiêu dùng của mình, bạn sẽ không biết bất kỳ sự phụ thuộc nào. Nhưng trái ngược với Singleton, SL thường sẽ khởi tạo tất cả các phụ thuộc cần thiết đằng sau hậu trường. Vì vậy, khi bạn tìm nạp một Dịch vụ, bạn sẽ không giống như Misko Hevery trong ví dụ về thẻ CreditCard , ví dụ như bạn không phải khởi tạo tất cả các phần phụ thuộc bằng tay.
Tìm nạp các phụ thuộc từ bên trong phiên bản cũng vi phạm Luật Demeter , quy định rằng bạn không nên đào sâu vào các cộng tác viên. Một phiên bản chỉ nên nói chuyện với các cộng tác viên trực tiếp của nó. Đây là một vấn đề với cả Singleton và ServiceLocator.
Trạng thái toàn cầu
Vấn đề của Global State cũng được giảm nhẹ phần nào vì khi bạn khởi tạo Bộ định vị dịch vụ mới giữa các lần kiểm tra, tất cả các phiên bản đã tạo trước đó cũng bị xóa (trừ khi bạn mắc lỗi và lưu chúng vào thuộc tính tĩnh trong SL). Tất nhiên, điều đó không đúng với bất kỳ trạng thái toàn cục nào trong các lớp do SL quản lý.
Ngoài ra, hãy xem Fowler trên Service Locator vs Dependency Injection để có một cuộc thảo luận chuyên sâu hơn.
Lưu ý về bản cập nhật của bạn và bài viết được liên kết của Sebastian Bergmann về mã thử nghiệm sử dụng Singletons : Không có cách nào khác, Sebastian gợi ý rằng giải pháp được đề xuất giúp việc sử dụng Singleons ít gặp vấn đề hơn. Đó chỉ là một cách để tạo mã mà nếu không sẽ không thể kiểm tra được nhiều hơn. Nhưng nó vẫn là mã có vấn đề. Trên thực tế, anh ấy ghi chú một cách rõ ràng: "Chỉ vì bạn có thể, không có nghĩa là bạn nên".