Thuật ngữ kỹ thuật để biểu thị ngược lại với tiêm phụ thuộc?


12

Đây là nhiều hơn một danh pháp (viết kỹ thuật) chứ không phải là một câu hỏi thuần túy kỹ thuật. Tôi đang cố gắng viết một đề xuất tái cấu trúc (và được chỉ định cho chính mình) tập trung vào việc mở rộng tiêm phụ thuộc trong ứng dụng của chúng tôi. Mặc dù chúng tôi sử dụng Spring để tự động đậu, nhưng vẫn có những trường hợp khởi tạo đậu bằng cách sử dụng MyClass obj = new MyClass(...), hoàn toàn có thể được tiêm. Tôi muốn làm cho đề xuất của tôi sử dụng danh pháp thanh lịch và tham khảo mẫu thiết kế đối lập với DI với một thuật ngữ thích hợp.

"Khớp nối chặt chẽ" có phải là một thuật ngữ thích hợp có nghĩa là từ trái nghĩa với DI không?


1
Có, khớp nối mô tả cả hành động sử dụng tên lớp rõ ràng trong các lớp khác và trạng thái kết quả của một cơ sở mã.
Kilian Foth

11
Không, khớp nối chặt chẽ chỉ mô tả thuộc tính của mã kết quả, không đối lập với DI. Bạn có thể sử dụng DI và vẫn có khớp nối chặt chẽ vì những lý do hoàn toàn khác nhau.
Doc Brown


@EricKing khoe. Nhân tiện +1.
candied_orange

1
"Phụ thuộc hút" .
SeldomNeedy

Câu trả lời:


30

Không. Khớp nối chặt chẽ hơn nhiều so với những gì liên quan đến tiêm chích phụ thuộc.

Phụ thuộc tiêm bên ngoài một quyết định thực hiện. Điều này đi một chặng đường dài để tách rời nhưng khớp nối không chỉ là điều này.

Một từ trái nghĩa tốt cho tiêm phụ thuộc là mã hóa cứng một phụ thuộc . Khi bạn xây dựng (sử dụng mới hoặc trực tiếp sử dụng một số nhà máy) bên trong một đối tượng hành vi, bạn đã làm mờ đi hai mối quan tâm khác nhau. Trình định vị dịch vụ giúp tách rời nhưng để bạn kết hợp với trình định vị dịch vụ.

Khớp nối không chỉ là phân tách xây dựng và hành vi. Nếu tôi có 101 phương thức phải được gọi theo một số thứ tự cụ thể từ lớp A đến lớp B, tôi sẽ liên kết chặt chẽ. Không quan trọng việc xây dựng và hành vi được phân tách tuyệt vời như thế nào.

Khớp nối là thước đo sự phụ thuộc lẫn nhau của hai đối tượng. Bất cứ điều gì góp phần làm cho khó thực hiện thay đổi trong một mà không ảnh hưởng đến cái khác là góp phần vào khớp nối. Phụ thuộc tiêm giúp với điều này nhưng nó không phải là tất cả.


Vâng, mã hóa cứng (một sự phụ thuộc), trái ngược với việc tiêm nó (trong thời gian chạy) là chính xác những gì tôi sẽ đề xuất, bạn cũng nhanh hơn tôi một chút.
Doc Brown

7
@DocBrown Đôi khi tôi ước nơi này không quá chú trọng đến việc nhanh. Tôi muốn nghe cách bạn đặt nó.
candied_orange

Câu trả lời tốt - tiêm phụ thuộc không ngụ ý tách rời. Tin tưởng khác đi xuống một con đường xấu
Ant P

1
@CandiedOrange Có lẽ ai đó nên đề xuất trong meta rằng câu trả lời sẽ bị ẩn trong một khoảng thời gian. Và / Hoặc số phiếu đó bị ẩn khỏi chế độ xem công khai trong Nnhiều giờ ... Hoặc cho đến khi câu trả lời được chọn. Tôi biết tôi không hoàn toàn khách quan khi một câu trả lời đã có 10 phiếu và 5 câu trả lời khác không có!
Svidgen

1
@svidgen tìm kiếm "súng nhanh nhất ở phía tây" trên meta. Vấn đề đã có một lịch sử lâu dài.
candied_orange

6

Nói một cách chính xác, Dependency Injection chỉ thực sự phản đối KHÔNG phụ thuộc vào tiêm chích - và do đó, bất kỳ chiến lược quản lý phụ thuộc nào không phải là Dependency Injection.

Khớp nối [không mong muốn], mặc dù không chính xác là một vấn đề trực giao, có thể xảy ra hoặc được giảm nhẹ theo một trong hai cách. Cả hai đều được kết hợp với DependencyClass:

public DependencyInjectedConstructor(DependencyClass dep) {
  dep.do();
}

public DependencyLookupConstructor() {
  var dep = new DependencyClass();
  dep.do();
}

DependencyLookupConstructorđược kết hợp với một cụ thể DependencyClasstrong trường hợp này. Nhưng, cả hai đều được ghép nối với DependencyClass. Tội ác thực sự, nếu có một ở đây, không nhất thiết phải là khớp nối, nó DependencyLookupConstructorcần phải thay đổi nếu DependencyClassđột nhiên cần sự phụ thuộc của chính nó vào 1 .

Tuy nhiên, hàm tạo / lớp này thậm chí còn được ghép lỏng lẻo hơn :

public DependencyLocatingConstructor() {
  var dep = ServiceLocator.GetMyDoer();
  dep.do();
}

Nếu bạn đang làm việc trong C #, những điều trên sẽ cho phép bạn ServiceLocatortrả lại bất cứ thứ gì khi GetMyDoer()được gọi, miễn là nó có thể có do()những gì DependencyLocatingConstructordo(). Bạn nhận được lợi ích của xác thực chữ ký thời gian biên dịch mà thậm chí không được ghép nối với giao diện hoàn chỉnh 2 .

Vì vậy, chọn chất độc của bạn.

Nhưng về cơ bản, nếu có một "đối nghịch" cụ thể của Dependency Injection, thì đó sẽ là một thứ khác trong lĩnh vực "Chiến lược quản lý phụ thuộc". Trong số những người khác, nếu bạn đã sử dụng bất kỳ điều nào sau đây trong cuộc trò chuyện, tôi sẽ nhận ra đó là việc KHÔNG phụ thuộc vào tiêm:

  • Mẫu định vị dịch vụ
  • Định vị phụ thuộc / Địa điểm
  • Đối tượng trực tiếp / phụ thuộc xây dựng
  • Phụ thuộc ẩn
  • "Không phụ thuộc tiêm"

1. Trớ trêu thay, một số vấn đề mà DI giải quyết ở các cấp cao hơn là kết quả của việc [sử dụng quá mức] khi sử dụng DI ở các cấp thấp hơn. Tôi đã có những niềm vui của làm việc trên codebases với độ phức tạp không cần thiết trên khắp như là kết quả của sức chứa số ít các nơi phức tạp mà thực sự giúp ... Tôi phải thừa nhận là thiên vị do tiếp xúc xấu.

2. Sử dụng vị trí dịch vụ cũng cho phép bạn dễ dàng chỉ định các phụ thuộc khác nhau cùng loại theo vai trò chức năng của chúng từ mã gọi , trong khi vẫn không rõ ràng về cách thức phụ thuộc được xây dựng. Giả sử bạn cần giải quyết Userhoặc IUsercho các mục đích khác nhau: Ví dụ, Locator.GetAdministrator()so với Locator.GetAuthor()- hoặc bất cứ điều gì. Mã của tôi có thể yêu cầu những gì nó cần về chức năng mà không cần biết nó hỗ trợ giao diện nào.


2
Sự cứu rỗi cho DependencyInjectedConstructor(DependencyClass dep)rằng DependencyClass có thể là một giao diện hoặc lớp trừu tượng. Đây là lý do tại sao nó làm tôi buồn khi các lập trình viên C # sử dụng tiền tố giao diện, như trong IDependency. Với tư cách là khách hàng, thực sự không phải việc của tôi là điều phụ thuộc này. Miễn là tôi không xây dựng nó, tất cả những gì tôi phải biết là làm thế nào để nói chuyện với nó. Vấn đề của người khác là gì.
candied_orange

Điểm là, DI vẫn kết nối bạn với giao diện đó và không yêu cầu đó DependencyClassphải là giao diện trừu tượng. Nó chỉ yêu cầu logic xây dựng / cấu hình / vị trí hiện có "ở một nơi khác." ... Chà, và liên tục hơn cho câu hỏi, vấn đề là DI không phải là "đối lập của khớp nối chặt chẽ" :)
svidgen

Trên thực tế ... tôi có thể hơi vượt quá giới hạn khi nói DI nhất thiết phải kết bạn với một giao diện, ngay cả trong C #. Mặc dù, tôi đã tránh chúng trong C #, tôi có ấn tượng rằng tôi cũng có thể chấp nhận dynamiccác tham số. (Nhưng không phải vartham số, nếu bộ nhớ phục vụ.) Vì vậy, với DI trong C #, tôi nghĩ rằng tôi phải mã hóa giao diện hoặc tôi phải hoàn toàn từ bỏ xác thực thời gian biên dịch.
Svidgen

Các đối tượng được ghép nối với các giao diện. Cho dù bạn có sử dụng từ khóa giao diện hay không. Đó là một giao diện thích hợp. Tất cả mọi thứ bạn phải được ghép nối với. Những gì bạn đun sôi là chi tiết triển khai và những thứ bổ sung bạn không cần. Chúng ta có thể chính thức hóa điều này bằng cách sử dụng từ khóa giao diện để cho khách hàng nói với thế giới, "Tất cả những gì tôi cần là cái này". Nhưng chúng ta không phải làm thế. Chúng ta có thể gõ vịt, trong một số ngôn ngữ.
candied_orange

Tôi không chắc chúng tôi hoàn toàn bất đồng. Nhưng, để làm rõ ... Các đối tượng được kết nối bên trong với các giao diện riêng của họ , vâng. Nhưng, bản thân giao diện chỉ áp đặt khớp nối phụ thuộc nếu giao diện được đặt tên rõ ràng. Trong C #, sử dụng dynamichoặc varvà nhận một đối tượng từ một trình định vị cho phép bạn bỏ qua giao diện và sử dụng bất kỳ lớp nào có thể do()những gì bạn cần, bất kể lớp đó có thực hiện IDoergiao diện nào đó không. Nói cách khác, nếu chúng ta có A-> B <-C, DI tách A khỏi C, nhưng nó yêu cầu cả A và C phải được ghép với B và ngăn chặn việc sử dụng D, ngay cả khi D sẽ do().
svidgen

2

Tôi không biết rằng có cụ thể, thuật ngữ ngành công nghiệp chấp nhận rộng rãi, nhưng lựa chọn thay thế mà tôi suy nghĩ bao gồm việc tạo ra nội dụ , tạo ra sự phụ thuộc nội bộ , phụ thuộc ở địa phương , hoặc phụ thuộc scoped tại địa phương .


2
tôi thích instance creationnhưng nó không đủ cụ thể DI tạo các thể hiện nhưng bằng phương tiện của bộ điều khiển chứ không phải ở cấp ứng dụng. có lẽinternal instance creation
lưỡng cư

1

Tôi sẽ đi với đóng gói phụ thuộc . Điều này thể hiện sự phụ thuộc bị khóa thay vì truy cập và rời đi một lần nữa.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.