Ở cấp độ, nó là dễ dàng.
'Dependency Injection' chỉ đơn giản trả lời câu hỏi "làm thế nào tôi tìm được cộng tác viên của mình" với "họ bị đẩy vào bạn - bạn không cần phải tự đi lấy chúng". (Nó tương tự như - nhưng không giống như - 'Đảo ngược điều khiển' trong đó câu hỏi "làm thế nào để tôi đặt hàng các hoạt động của mình trên đầu vào?" Có câu trả lời tương tự).
Các chỉ lợi ích mà có cộng tác viên của bạn đẩy vào bạn là cho phép mã khách hàng để sử dụng lớp học của bạn để soạn một đồ thị đối tượng đó phù hợp với nhu hiện tại của nó ... bạn có không được tự ý xác định trước hình dáng và mutability của đồ thị bằng cách tư nhân quyết định các loại cụ thể và vòng đời của các cộng tác viên của bạn.
(Tất cả những lợi ích khác, về khả năng kiểm tra, của khớp nối lỏng lẻo, v.v., phần lớn đến từ việc sử dụng các giao diện và không quá nhiều từ sự phụ thuộc-tiêm-tiêm, mặc dù DI tự nhiên thúc đẩy việc sử dụng các giao diện).
Điều đáng chú ý là, nếu bạn tránh khởi tạo các cộng tác viên của riêng mình, do đó , lớp của bạn phải lấy các cộng tác viên của nó từ một hàm tạo, một thuộc tính hoặc một đối số phương thức (tùy chọn sau này thường bị bỏ qua không phải lúc nào cũng có ý nghĩa đối với các cộng tác viên của một lớp là một phần của 'trạng thái' của nó).
Và đó là một điều tốt.
Ở cấp ứng dụng ...
Quá nhiều cho quan điểm trên mỗi lớp. Giả sử bạn có một nhóm các lớp tuân theo quy tắc "không khởi tạo các cộng tác viên của riêng bạn" và muốn tạo một ứng dụng từ họ. Điều đơn giản nhất để làm là sử dụng mã cũ tốt (một công cụ thực sự hữu ích để gọi các hàm tạo, thuộc tính và phương thức!) Để soạn đồ thị đối tượng bạn muốn và ném một số đầu vào vào nó. (Vâng, một số đối tượng trong biểu đồ của bạn sẽ là các nhà máy đối tượng, được chuyển qua làm cộng tác viên cho các đối tượng tồn tại lâu khác trong biểu đồ, sẵn sàng phục vụ ... bạn không thể xây dựng trước mọi đối tượng! ).
... bạn cần 'linh hoạt' định cấu hình biểu đồ đối tượng của ứng dụng ...
Tùy thuộc vào các mục tiêu khác (không liên quan đến mã) của bạn, bạn có thể muốn cung cấp cho người dùng cuối một số quyền kiểm soát đối với biểu đồ đối tượng do đó được triển khai. Điều này dẫn bạn theo hướng của sơ đồ cấu hình, loại này hay loại khác, cho dù đó là tệp văn bản của thiết kế của riêng bạn với một số cặp tên / giá trị, tệp XML, DSL tùy chỉnh, ngôn ngữ mô tả biểu đồ khai báo, chẳng hạn như YAML, một ngôn ngữ kịch bản bắt buộc như JavaScript hoặc một ngôn ngữ khác phù hợp với nhiệm vụ hiện tại. Bất cứ điều gì cần thiết để soạn một biểu đồ đối tượng hợp lệ, theo cách đáp ứng nhu cầu của người dùng của bạn.
... Có thể là một lực lượng thiết kế đáng kể.
Trong hoàn cảnh khắc nghiệt nhất của loại đó, bạn có thể chọn cách tiếp cận rất chung chung và cung cấp cho người dùng cuối một cơ chế chung để 'nối dây' biểu đồ đối tượng mà họ chọn và thậm chí cho phép họ cung cấp các giao diện cụ thể cho giao diện thời gian chạy! (Tài liệu của bạn là một viên ngọc sáng, người dùng của bạn rất thông minh, quen thuộc với ít nhất là phác thảo thô của biểu đồ đối tượng của ứng dụng của bạn, nhưng không có trình biên dịch tiện dụng). Kịch bản này về mặt lý thuyết có thể xảy ra trong một số tình huống 'doanh nghiệp'.
Trong trường hợp đó, bạn có thể có một ngôn ngữ khai báo cho phép người dùng của bạn thể hiện bất kỳ loại nào, thành phần của biểu đồ đối tượng của các loại đó và bảng giao diện mà người dùng cuối huyền thoại có thể trộn và khớp. Để giảm tải nhận thức cho người dùng của bạn, bạn thích cách tiếp cận 'cấu hình theo quy ước', để họ chỉ phải bước vào và vượt qua sự quan tâm của đồ thị đối tượng, thay vì vật lộn với toàn bộ.
Bạn nghèo quá!
Bởi vì bạn không thích tự viết ra tất cả những điều đó (nhưng nghiêm túc, hãy kiểm tra ràng buộc YAML cho ngôn ngữ của bạn), bạn đang sử dụng một khuôn khổ DI nào đó.
Tùy thuộc vào sự trưởng thành của khung đó, bạn có thể không có tùy chọn sử dụng hàm tạo, ngay cả khi nó có ý nghĩa (các cộng tác viên không thay đổi trong suốt vòng đời của một đối tượng), do đó buộc bạn phải sử dụng Setter Injection (ngay cả khi cộng tác viên không thay đổi trong suốt vòng đời của một đối tượng và ngay cả khi không thực sự có lý do hợp lý tại sao tất cả các triển khai cụ thể của giao diện phải có cộng tác viên của một loại cụ thể). Nếu vậy, bạn hiện đang ở trong địa ngục khớp nối mạnh mẽ, mặc dù đã siêng năng 'giao diện được sử dụng' trong toàn bộ cơ sở mã của bạn - kinh dị!
Mặc dù vậy, hy vọng rằng bạn đã sử dụng khung DI cung cấp cho bạn tùy chọn tiêm xây dựng và người dùng của bạn chỉ hơi khó chịu vì không dành nhiều thời gian suy nghĩ về những điều cụ thể họ cần để định cấu hình và cung cấp cho họ giao diện người dùng phù hợp hơn với nhiệm vụ trong tầm tay (Mặc dù công bằng mà nói, có lẽ bạn đã cố gắng nghĩ ra một cách, nhưng JavaEE đã làm bạn thất vọng và bạn phải dùng đến cách hack khủng khiếp này).
Bootnote
Bạn chưa bao giờ sử dụng Google Guice, điều này cung cấp cho bạn bộ mã hóa một cách để phân phối với nhiệm vụ soạn một biểu đồ đối tượng bằng mã ... bằng cách viết mã. Argh!