2013-06-17 35 views
7

Tôi hiểu rằng nguyên tắc Injection Dependency là tất cả về mã tách. Thay vì làm mới trường hợp trong các lớp học, thay vào đó bạn tiêm chúng, làm cho chúng lỏng lẻo cùng.Dependency Injection Container vs Mẫu đăng ký

Bây giờ nếu tôi phải truyền một tập hợp các đối tượng sẽ được sử dụng thông qua một số lớp trong ứng dụng của tôi, tôi có thể tạo một thùng chứa (thường được gọi là thùng chứa phụ thuộc).

Đó chính xác là những gì tôi đang làm vì tôi phải truyền đối tượng cấu hình, đối tượng logger, đối tượng dịch, v.v ... sẽ được sử dụng thông qua một số trường hợp của ứng dụng của tôi. Tôi đang chuyển toàn bộ vùng chứa thông qua một số lớp, ngay cả khi không phải tất cả các lớp đều cần truy cập vào tất cả các đối tượng trong vùng chứa. Điều này dẫn tôi đến câu hỏi sau: sự khác biệt là gì nếu tôi tạo một Registry toàn cục và đặt các đối tượng vào đó, sau đó lấy chúng như Registry :: getInstance() -> get ('logger'); ? Mặc dù tôi sử dụng một đăng ký toàn cầu hoặc một thùng chứa phụ thuộc, các thành phần lớp sẽ có quyền truy cập vào tất cả các đối tượng trong vùng chứa hoặc đăng ký, ngay cả khi chúng không cần xem/truy cập tất cả chúng.

Kết luận: Sự khác biệt là gì nếu tôi vượt qua một thùng chứa phụ thuộc tiêm dọc theo các lớp học của tôi hoặc một Cơ quan đăng ký toàn cầu?

+0

Như tôi hiểu nếu bạn đang tiêm container vào lớp, đây là vị trí dịch vụ không phải là sự tiêm phụ thuộc. – Orangepill

+0

thì những gì được gọi là một container tiêm phụ thuộc? – Matthew

+0

Như tôi đã hiểu, Dependency Injection luôn có sự phụ thuộc từ bên ngoài lớp trong khi Service Location có thể xảy ra ở bất cứ đâu. Điều xấu với dịch vụ định vị là họ ẩn những gì phụ thuộc thực sự cho một đối tượng được. – Orangepill

Trả lời

5

Tôi nghĩ điểm bị thiếu ở đây là CompositionRoot.Đối với DI Nguyên tắc khi bạn xác định các ràng buộc của bạn trong Root Root, bạn có thể sử dụng tham chiếu trong toàn bộ ứng dụng. Đó là giá trị DI Container mang lại.

Theo định nghĩa "Gốc thành phần là vị trí duy nhất (tốt nhất) trong ứng dụng nơi các mô đun được tạo thành cùng nhau".

Tôi sẽ thêm rằng Root Root cũng là một vị trí duy nhất nơi tất cả các quyết định quan trọng về hành vi ứng dụng của bạn diễn ra. Đó là những gì đối tượng để sử dụng trong tình huống nào. Đây là trái tim của một hệ thống OO, nơi sự tương tác giữa các đối tượng mang lại hành vi của hệ thống.

+0

Nếu tôi hiểu chính xác, Root Root trong một ứng dụng dựa trên PHP MVC sẽ là bootstrap hoặc một lớp gần bootstrap. Ở đó tôi sẽ xây dựng các lớp học của tôi và tiêm phụ thuộc của họ. Nhưng điều đó dẫn tôi đến một câu hỏi: trong trường hợp này tôi không thể xây dựng các thành phần của mình một cách năng động, vì tất cả các phụ thuộc phải được thiết lập tại điểm vào ứng dụng. – Matthew

+2

Bài viết này đã trả lời nhận xét cuối cùng của tôi: http://richardmiller.co.uk/2011/07/07/dependency-injection-moving-from-basics-to-container/ – Matthew

6

Lưu ý: đôi khi mọi người sử dụng Đăng ký bằng các tên khác nhau. Những thứ phổ biến mà tôi đã thấy là: Locator, Context and System.

Sử dụng Registry toàn cục làm cho mã của bạn được gắn với tên lớp của Cơ quan đăng ký nói trên. Nó có nghĩa là bạn không thể kiểm tra mã của bạn một cách độc lập. Và cách thức, làm thế nào đăng ký được thiết lập, nằm cho bạn: bạn không bao giờ có thể biết được trường hợp sẽ được yêu cầu.

Khá phổ biến khi mọi người nhầm lẫn DI Containers with Registries.

DI Vùng chứa không phải là thứ bạn đưa vào lớp học. Thay vào đó nó là một sự tăng cường cho các nhà máy: nó xác định rằng lớp Foo yêu cầu thể hiện của Bar để được tiêm vào hàm tạo. Sau đó, tùy thuộc vào thiết lập, nó sẽ mua lại phiên bản mới Bar hoặc sử dụng phiên bản hiện tại, để cung cấp sự phụ thuộc cho biết.

  • Trong một nhà máy đơn giản, bạn thường phải mã hóa cứng phụ thuộc, sẽ được tiêm. Trong tình huống này, những gì nhà máy có thể xây dựng, được giới hạn bởi "dấu chân" của nhà xây dựng của lớp.

  • Khi nhà máy sử dụng làm vùng chứa DI, nó có thể tạo ra các phiên bản với các phụ thuộc khác nhau. Trong thiết lập này, các nhà máy của bạn tập trung vào việc xây dựng các cá thể được gắn với một số nhóm các lớp logic (hoặc các cấp độ cao khác) của các không gian tên cụ thể.

+0

Có phải là một tuyên bố đúng rằng tất cả DIC có thể được sử dụng như một định vị dịch vụ và sự khác biệt lớn giữa hai mẫu này là nhiều hơn. so với cách (Container/Locator) được triển khai. – Orangepill

+0

@ tereško, đọc câu trả lời của bạn, tôi có nên hiểu rằng sổ đăng ký (hoặc định vị dịch vụ) cho phép truy cập vào các đối tượng và DIC giống một Nhà máy biết cách tạo * các đối tượng này không? Nó không có ý nghĩa sau đó để so sánh hai mô hình và DIC không phải là một thay thế cho Registry? Mặc dù có vẻ như bạn đề nghị để tránh Registry, ủng hộ một giải pháp khác? – Matthew

+0

Tôi sẽ nói rằng một hệ thống DIC được triển khai đầy đủ sẽ sử dụng một đăng ký không tĩnh, không toàn cầu làm bộ đệm cho các phiên bản khởi tạo. Registry là tất cả về lưu trữ các đối tượng. DI container là về việc khám phá ra những yêu cầu mà một lớp có để tạo ra một cá thể. Cho dù container DI tự tạo ra cá thể hay để nó vào nhà máy thì câu hỏi càng được ưu tiên. –

0

Tôi đồng ý với hầu hết những gì teresko đã nói và tôi muốn thêm một số điểm:

  • Nếu bạn cảm thấy rằng dịch vụ của bạn được chia sẻ giữa nhiều trường hợp khác nhau thì bạn có thể đăng ký chúng như Singeltons với các container nhưng sau đó bạn sẽ phải suy nghĩ về đa luồng nếu nó là một vấn đề cho bạn.
  • Bất cứ khi nào bạn cảm thấy lưng mình chống lại bức tường trong trường hợp tiêm phụ thuộc thì hãy nhớ rằng các nhà máy (Abstract Factory Pattern) hầu như luôn là giải pháp.
  • Các dịch vụ mà bạn đề cập có vẻ giống như một mối quan tâm chéo, vì vậy tôi sẽ sử dụng các kỹ thuật AOP để tránh làm đầy codebase của tôi với những lo ngại này, điều này sẽ làm cho mã sạch hơn nhiều.
Các vấn đề liên quan