nhanh Chuyển tiếp:Hiểu IoC Container và Dependency Injection
Tôi viết thư này với mục đích nhận được một sự hiểu biết tốt hơn về dependency injection và container IoC, nhưng cũng vì thế mà sau đó tôi có thể sửa chữa những sai lầm trong nó và sử dụng nó để giúp dạy cho một vài người bạn của tôi về họ.
Hiện tại, tôi đã đọc qua tài liệu cho nhiều khung công tác khác nhau (laravel, fuel, codeigniter, symfony) và tôi thấy rằng có quá nhiều khía cạnh khác nhau của khung công tác mà tôi cần phải cảm thấy thoải mái khi sử dụng quyết định cố gắng tìm hiểu từng phần chính một cách riêng lẻ trước khi cố gắng sử dụng chúng trong chính các khung công tác.
Tôi đã dành hàng giờ để tìm hiểu các ý nghĩa khác nhau, xem qua phản hồi ngăn xếp và đọc các bài viết khác nhau để hiểu IoC là gì và cách sử dụng nó để quản lý phụ thuộc một cách chính xác và tôi tin rằng tôi hiểu ý nghĩa của nó. Tôi vẫn còn màu xám về cách thực hiện nó một cách chính xác. Tôi nghĩ cách tốt nhất để mọi người đọc điều này để giúp tôi là đưa ra những hiểu biết hiện tại về container IoC và tiêm phụ thuộc, và sau đó để những người có hiểu biết tốt hơn tôi chỉ ra nơi hiểu biết của tôi thiếu.
hiểu biết của tôi:
- Một phụ thuộc là khi một thể hiện của ClassA đòi hỏi một thể hiện của ClassB để nhanh chóng một thể hiện mới của ClassA.
- Tiêm phụ thuộc là khi ClassA được chuyển một thể hiện của ClassB, hoặc thông qua một tham số trong hàm tạo của ClassA hoặc thông qua một hàm ~ DependencyNameHere ~ (~ DependencyNameHere ~ $ param). (Đây là một trong những khu vực tôi không hoàn toàn chắc chắn).
- Vùng chứa IoC là một lớp đơn (chỉ có thể có 1 thể hiện tại bất kỳ thời điểm nào), nơi cách thức cụ thể của các đối tượng instantiating của lớp đó cho dự án này có thể được đăng ký. Here's a link to an example of what I'm trying to describe along with the class definition for the IoC container I've been using
Vì vậy, tại thời điểm này, tôi bắt đầu thử sử dụng vùng chứa IoC cho các tình huống phức tạp hơn. Bây giờ có vẻ như để sử dụng container IoC, tôi bị giới hạn bởi một mối quan hệ có-một cho khá nhiều lớp mà tôi muốn tạo ra có các phụ thuộc mà nó muốn định nghĩa trong thùng chứa IoC. Điều gì xảy ra nếu tôi muốn tạo một lớp thừa kế một lớp, nhưng chỉ khi lớp cha đã được tạo theo một cách cụ thể mà nó đã được đăng ký trong thùng chứa IoC. Ví dụ: Tôi muốn tạo một lớp con của mysqli, nhưng tôi muốn đăng ký lớp này trong thùng chứa IoC để chỉ khởi tạo với lớp cha được xây dựng theo cách mà trước đây tôi đã đăng ký trong thùng chứa IoC. Tôi không thể nghĩ ra một cách để làm điều này mà không cần sao chép mã (và vì đây là một dự án học tập, tôi đang cố gắng giữ nó như là 'thuần khiết' nhất có thể). Here are some more examples of what I am trying to describe.
Vì vậy, đây là một số câu hỏi của tôi:
- phải là những gì tôi đang cố gắng để làm trên có thể mà không vi phạm một số nguyên tắc OOP? Tôi biết trong c + + Tôi có thể sử dụng bộ nhớ động và một nhà xây dựng bản sao để thực hiện nó, nhưng tôi đã không thể tìm thấy loại chức năng trong php.(Tôi sẽ thừa nhận rằng tôi có rất ít kinh nghiệm sử dụng bất kỳ phương pháp ma thuật nào khác ngoài __construct, nhưng từ đọc và __clone nếu tôi hiểu đúng, tôi không thể sử dụng trong hàm tạo nó để làm cho lớp con được khởi tạo một bản sao của một ví dụ của lớp cha).
- Tất cả các định nghĩa lớp phụ thuộc của tôi nên liên quan đến IoC ở đâu? (IoC.php của tôi có nên có một loạt các require_once ('dependencyClassDefinition.php') ở đầu? Phản ứng ruột của tôi là có một cách tốt hơn, nhưng tôi đã không đưa ra một chưa)
- Tệp gì Tôi có nên đăng ký đối tượng của mình không? Hiện đang thực hiện tất cả các cuộc gọi tới IoC :: register() trong tệp IoC.php sau khi định nghĩa lớp.
- Tôi có cần đăng ký phụ thuộc vào IoC trước khi đăng ký một lớp cần sự phụ thuộc đó không? Vì tôi không gọi hàm ẩn danh cho đến khi tôi thực sự khởi tạo một đối tượng được đăng ký trong IoC, tôi đoán là không, nhưng nó vẫn là một mối quan tâm.
- Có điều gì khác mà tôi đang xem mà tôi nên làm hoặc sử dụng không? Tôi đang cố gắng thực hiện từng bước một, nhưng tôi cũng không muốn biết rằng mã của tôi sẽ được tái sử dụng và quan trọng nhất là ai đó không biết gì về dự án của tôi có thể đọc và hiểu nó.
Tôi biết điều này rất dài, và chỉ muốn cảm ơn trước bất kỳ ai dành thời gian đọc nó, và thậm chí nhiều hơn để mọi người chia sẻ kiến thức của họ.
Với ví dụ này, nó trông giống như những gì bạn đang tạo ra là các nhà máy như một mảng kết hợp được tôn vinh (biến '$ dic' này). Pimple là một mảng kết hợp được tôn vinh. Gọi '$ dic-> resolve()' là một trình định vị dịch vụ và tạo ra một kẻ nói dối về API đối tượng của bạn. Bạn đọc Fowler và các cuộc đàm phán mã sạch - chưa cung cấp mụn và chống mẫu như là giải pháp. Tôi nghĩ rằng bạn cần phải nghĩ lại phần trên '$ database =' ... nếu không thì sẽ rất tuyệt khi thấy ai đó nói rằng không sử dụng statics :-) – Jimbo
@Jimbo Nó chỉ là một dịch vụ định vị nếu bạn sử dụng nó như một chuyển nó xung quanh cho các vật thể của bạn, đó là điều tôi cảnh báo rõ ràng trong câu trả lời của tôi. Không có gì "chống khuôn mẫu" trong việc sử dụng một container đơn giản tương tự để xây dựng đồ thị đối tượng của bạn ở một nơi duy nhất ở đâu đó gần điểm vào của ứng dụng, mặc dù. BTW, có rất nhiều thứ có thể phát triển thành "mảng kết hợp tôn vinh" bằng ngôn ngữ có mảng liên kết/hashmaps là một trong rất ít các loại lõi không vô hướng ;-) – lafor
Lol, điểm công bằng. Tuy nhiên, '$ database = $ dic-> resolve ('database');' và cảnh báo của định vị dịch vụ dường như không được liên kết. Tôi đã không nhận được rằng có một cảnh báo cho việc sử dụng này. Nếu bạn quan tâm đến loại công cụ này, hãy để tôi thổi tâm trí của bạn: [link] (https://github.com/rdlowrey/Auryn). – Jimbo