[Trước khi bắt đầu, hãy để tôi nói rằng tôi chủ yếu là một lập trình viên Java - chỉ với một chút kiến thức về PHP. Nhưng tôi sẽ chỉ đơn giản là cố gắng để có được những khái niệm quan trọng nhất trên mà không cần chi tiết cụ thể ngôn ngữ]
Dependency Injection dựa trên hai phần mã:.
- Xây dựng
- Thực hiện
Trong hình dạng cực đoan nhất của nó, không có các toán tử new
nào được tìm thấy trong phần Thực thi. Tất cả chúng đều được chuyển vào phần Xây dựng. (Trong thực tế, điều này sẽ được giảm bớt.)
Tất cả việc xây dựng xảy ra - trong phần Xây dựng. Nó tạo ra đồ thị của các đối tượng cần thiết để thực thi dưới lên. Vì vậy, chúng ta hãy giả định, cần xây dựng A:
- Một phụ thuộc vào B, và
- B phụ thuộc vào C.
Sau đó
- C được xây dựng đầu tiên.
- Sau đó, B được tạo bằng C làm tham số.
- Sau đó, A được tạo bằng B làm tham số.
Vì vậy, C không phải được chuyển thành tham số hàm tạo cho A. Ví dụ nhỏ này không minh họa đủ mạnh, số lượng đối tượng này phải được chuyển xung quanh khá nhỏ đến mức nào con số.
Chính bản thân bộ phận phụ thuộc không được chuyển vào phần thi hành. Đây là một trong những sai lầm cơ bản mà mọi người (kể cả bản thân tôi) cố gắng thực hiện, khi họ lần đầu tiên tiếp xúc với DI. Vấn đề là, điều này sẽ làm mờ hoàn toàn ranh giới giữa Xây dựng và Thi hành. Một cách khác để nói rằng, nó sẽ vi phạm Law of Demeter. Hoặc trong mô hình nói: Nó cuối cùng sẽ "làm suy thoái" mẫu Dependency Injection thành mẫu Locator Service. Nó gây tranh cãi, nếu điều này thực sự là một sự suy thoái, nhưng trong mọi trường hợp nó thường không phải là một ý tưởng tốt để sử dụng sai Dependency Injector như một Service Locator. Vì vậy, bất cứ khi nào bạn cần cung cấp cho một trong các đối tượng được xây dựng của bạn khả năng tạo ra các đối tượng khác trong quá trình thực thi, thay vì truyền đi Dependency Injector, bạn sẽ chỉ chuyển các Nhà cung cấp đơn giản (một thuật ngữ được sử dụng bởi khung Java DI Guice). Đây là những lớp học khá đơn giản chỉ có thể tạo ra một loại đối tượng nhất định. Họ có điểm tương đồng với một nhà máy.
Trước tiên, hãy cố chuyển các phụ thuộc bắt buộc trực tiếp cho hàm tạo.
Vì vậy, để tóm tắt:
- xây dựng các đối tượng từ dưới lên.
- Chỉ chuyển một số phụ thuộc theo yêu cầu để tạo đối tượng.
- Khi bạn đã hoàn tất, hãy bắt đầu thực hiện.
- Trong khi thực hiện, bạn vẫn có thể tìm nạp đối tượng mới được tạo bằng cách sử dụng Nhà cung cấp.
Nhưng đừng mang nó quá xa: đối tượng đơn giản vẫn có thể được tạo ra mà không có một nhà cung cấp :-)
Và bây giờ, tất cả các bạn sẽ phải làm là để dịch công cụ này vào mã chất lượng. Có lẽ những người khác có thể giúp bạn với một vài ví dụ PHP.
Phụ lục: hơn một chút về cung cấp
Như đã đề cập ở trên, khái niệm "Nhà cung cấp" (một nhà máy chuyên dùng) là một chút cụ thể cho các khuôn khổ Java DI Guice. Khung công tác này có thể tự động tạo Nhà cung cấp cho bất kỳ loại đối tượng nào. Tuy nhiên, khái niệm này thường hữu ích cho DI. Sự khác biệt duy nhất là, nếu không có sự trợ giúp của Guice hoặc một khuôn khổ tương tự, bạn sẽ phải tự viết Nhà cung cấp - nhưng điều đó khá dễ dàng:
Giả sử, B phụ thuộc vào C.
- Nếu B chỉ cần một trường hợp cố định của C, sau đó bạn không cần một nhà cung cấp - bạn chỉ có thể xây dựng B với các đối số constructor C.
- Nếu B cần phải tạo thêm trường hợp của C trong quá trình thực , sau đó chỉ cần viết một lớp được gọi là
CProvider
với phương thức get()
, có thể tạo một phiên bản mới của C. Sau đó, chuyển trường hợp CProvider
vào hàm tạo B và lưu trữ Nhà cung cấp trong trường thể hiện B. Bây giờ B có thể gọi cProvider.get()
khi cần một phiên bản mới của C.
Nhà cung cấp là một phần của mã Xây dựng, vì vậy bạn được phép sử dụng new C(...)
! Mặt khác, chúng không phải là một phần của mã Execution, vì vậy bạn không nên có bất kỳ logic thực thi nào ở đó.
CProvider
có thể được chuyển vào nhiều nhà thầu trong khóa học. Bạn cũng có thể viết nhiều phiên bản CProvider1
, CProvider2
, ... - nơi mỗi người có thể tạo các phiên bản khác nhau của các đối tượng C với các thuộc tính khác nhau. Hoặc bạn khởi tạo đơn giản CProvider
nhiều lần với các đối số khác nhau.
Cái nhìn sâu sắc, cảm ơn lời giải thích. Tôi biết về mô hình Dịch vụ định vị và đó không phải là những gì tôi đang cố gắng hoàn thành. Bạn có thể vui lòng xây dựng một chút về việc sử dụng các nhà cung cấp? – Andre
Đã thêm phụ lục. Hãy cho tôi biết nếu bạn cần thêm thông tin. –
Cảm ơn bạn rất nhiều vì đã giúp đỡ. Về cơ bản, tôi cần phải vượt qua các nhà cung cấp được yêu cầu cho mỗi phụ thuộc nhiều phiên bản. Đây là những mẫu cơ bản của Nhà máy nhưng cụ thể để tạo ra các đối tượng cho một mục đích (có thể là một loạt các lớp, một ví dụ sẽ là các trình điều khiển đầu ra) và trả về chúng cho lớp phụ thuộc. Nghe có vẻ phức tạp hơn: D – Andre