Điều này tương tự như câu trả lời được nêu lên nhưng tôi muốn nghĩ to - có lẽ những người khác cũng nhìn mọi thứ theo cách này.
OO cổ điển sử dụng các nhà xây dựng để xác định hợp đồng "khởi tạo" công khai cho người tiêu dùng của lớp (ẩn TẤT CẢ chi tiết triển khai; còn gọi là đóng gói). Hợp đồng này có thể đảm bảo rằng sau khi khởi tạo, bạn có một đối tượng sẵn sàng sử dụng (nghĩa là không có các bước khởi tạo bổ sung nào được ghi nhớ (er, quên) bởi người dùng).
(constructor) DI không thể phủ nhận phá vỡ đóng gói bằng cách chảy máu chi tiết cấy ghép thông qua giao diện xây dựng công cộng này. Miễn là chúng tôi vẫn xem xét nhà xây dựng công cộng chịu trách nhiệm xác định hợp đồng khởi tạo cho người dùng, chúng tôi đã tạo ra một vi phạm khủng khiếp về đóng gói.
Ví dụ lý thuyết:
Class Foo có 4 phương thức và cần một số nguyên để khởi tạo, do đó, hàm tạo của nó trông giống Foo (kích thước int) và ngay lập tức rõ ràng với người dùng của lớp Foo rằng họ phải cung cấp một kích thước ngay lập tức để Foo hoạt động.
Nói rằng việc triển khai đặc biệt này của Foo cũng có thể cần một IWidget để thực hiện công việc của mình. Trình xây dựng nội dung của phụ thuộc này sẽ cho chúng ta tạo một hàm tạo như Foo (kích thước int, tiện ích IWidget)
Điều làm tôi bực mình là bây giờ chúng ta có một hàm tạo kết hợp dữ liệu khởi tạo với các phụ thuộc - một đầu vào được người dùng của lớp ( kích thước ) quan tâm, cái còn lại là một phụ thuộc bên trong chỉ phục vụ gây nhầm lẫn cho người dùng và là một triển khai chi tiết ( phụ tùng ).
Tham số kích thước KHÔNG phải là phụ thuộc - đơn giản là giá trị khởi tạo theo thể hiện. IoC là tuyệt vời cho các phụ thuộc bên ngoài (như widget) nhưng không cho khởi tạo trạng thái nội bộ.
Thậm chí tệ hơn, điều gì xảy ra nếu Widget chỉ cần thiết cho 2 trong 4 phương thức trên lớp này; Tôi có thể phải chịu chi phí tức thời cho Widget mặc dù có thể không được sử dụng!
Làm thế nào để thỏa hiệp / hòa giải điều này?
Một cách tiếp cận là chuyển đổi độc quyền sang các giao diện để xác định hợp đồng hoạt động; và bãi bỏ việc sử dụng các nhà xây dựng bởi người dùng. Để thống nhất, tất cả các đối tượng sẽ chỉ được truy cập thông qua các giao diện và chỉ được khởi tạo thông qua một số dạng trình phân giải (như bộ chứa IOC / DI). Chỉ có container được khởi tạo mọi thứ.
Điều đó quan tâm đến sự phụ thuộc của Widget, nhưng làm thế nào để chúng ta khởi tạo "kích thước" mà không cần dùng đến một phương thức khởi tạo riêng biệt trên giao diện Foo? Sử dụng giải pháp này, chúng tôi đã mất khả năng đảm bảo rằng một phiên bản của Foo được khởi tạo hoàn toàn vào thời điểm bạn nhận được cá thể. Bummer, bởi vì tôi thực sự thích ý tưởng và sự đơn giản của tiêm constructor.
Làm cách nào để tôi đạt được khởi tạo được đảm bảo trong thế giới DI này, khi khởi tạo THÊM hơn CHỈ phụ thuộc bên ngoài?