Gần đây tôi đã đọc bài viết của Mark Seemann về mô hình chống định vị dịch vụ.
Tác giả chỉ ra hai lý do chính tại sao ServiceLocator là một mô hình chống:
Vấn đề sử dụng API (mà tôi hoàn toàn ổn)
Khi lớp sử dụng trình định vị dịch vụ, rất khó để thấy các phụ thuộc của nó vì, trong hầu hết các trường hợp, lớp chỉ có một hàm tạo PARAMETERLESS. Ngược lại với ServiceLocator, cách tiếp cận DI phơi bày rõ ràng các phụ thuộc thông qua các tham số của hàm tạo để các phụ thuộc được nhìn thấy dễ dàng trong IntelliSense.Vấn đề bảo trì (đánh đố tôi)
Hãy xem xét các ví dụ sau
Chúng tôi có một lớp 'MyType' sử dụng phương pháp định vị dịch vụ:
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}
}
Bây giờ chúng tôi muốn thêm một phụ thuộc khác vào lớp 'MyType'
public class MyType
{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}
}
Và đây là nơi hiểu lầm của tôi bắt đầu. Tác giả nói:
Nó trở nên khó khăn hơn rất nhiều để nói liệu bạn có đang giới thiệu một sự thay đổi đột phá hay không. Bạn cần hiểu toàn bộ ứng dụng mà Bộ định vị dịch vụ đang được sử dụng và trình biên dịch sẽ không giúp bạn.
Nhưng đợi một chút, nếu chúng ta đang sử dụng phương pháp DI, chúng tôi sẽ giới thiệu một phụ thuộc với một tham số khác trong hàm tạo (trong trường hợp hàm tạo của hàm tạo). Và vấn đề sẽ vẫn còn đó. Nếu chúng ta có thể quên thiết lập ServiceLocator, thì chúng ta có thể quên thêm ánh xạ mới vào bộ chứa IoC và cách tiếp cận DI sẽ có cùng một vấn đề về thời gian chạy.
Ngoài ra, tác giả đã đề cập về những khó khăn thử nghiệm đơn vị. Nhưng, chúng ta sẽ không có vấn đề với phương pháp DI chứ? Chúng ta có cần cập nhật tất cả các bài kiểm tra bắt đầu lớp đó không? Chúng tôi sẽ cập nhật chúng để vượt qua một phụ thuộc bị chế giễu mới chỉ để làm cho bài kiểm tra của chúng tôi có thể biên dịch được. Và tôi không thấy bất kỳ lợi ích nào từ bản cập nhật và chi tiêu thời gian đó.
Tôi không cố gắng bảo vệ phương pháp tiếp cận dịch vụ định vị. Nhưng sự hiểu lầm này khiến tôi nghĩ rằng tôi đang mất đi thứ gì đó rất quan trọng. Ai đó có thể xua tan nghi ngờ của tôi?
CẬP NHẬT (TÓM TẮT):
Câu trả lời cho câu hỏi của tôi "Bộ định vị dịch vụ có phải là mẫu chống" thực sự phụ thuộc vào hoàn cảnh. Và tôi chắc chắn sẽ không đề xuất gạch bỏ nó khỏi danh sách công cụ của bạn. Nó có thể trở nên rất tiện dụng khi bạn bắt đầu xử lý mã kế thừa. Nếu bạn đủ may mắn để bắt đầu dự án của mình thì phương pháp DI có thể là lựa chọn tốt hơn vì nó có một số lợi thế so với Trình định vị dịch vụ.
Và đây là những khác biệt chính đã thuyết phục tôi không sử dụng Trình định vị dịch vụ cho các dự án mới của mình:
- Rõ ràng và quan trọng nhất: Trình định vị dịch vụ che giấu các phụ thuộc lớp
- Nếu bạn đang sử dụng một số bộ chứa IoC, nó có thể sẽ quét tất cả các hàm tạo khi khởi động để xác thực tất cả các phụ thuộc và cung cấp cho bạn phản hồi ngay lập tức về ánh xạ bị thiếu (hoặc cấu hình sai); điều này là không thể nếu bạn đang sử dụng bộ chứa IoC của mình làm Trình định vị dịch vụ
Để biết chi tiết đọc câu trả lời tuyệt vời được đưa ra dưới đây.