Tôi hiểu lợi ích của chính việc tiêm phụ thuộc. Hãy lấy Spring làm ví dụ. Tôi cũng hiểu lợi ích của các tính năng khác của Spring như AOP, các loại trợ giúp khác nhau, v.v. Tôi chỉ tự hỏi, cấu hình XML có những lợi ích gì, chẳng hạn như:
<bean id="Mary" class="foo.bar.Female">
<property name="age" value="23"/>
</bean>
<bean id="John" class="foo.bar.Male">
<property name="girlfriend" ref="Mary"/>
</bean>
so với mã java cũ thuần túy như:
Female mary = new Female();
mary.setAge(23);
Male john = new Male();
john.setGirlfriend(mary);
được gỡ lỗi dễ dàng hơn, kiểm tra thời gian biên dịch và có thể hiểu được bởi bất kỳ ai chỉ biết java. Vậy mục đích chính của khung tiêm phụ thuộc là gì? (hoặc một đoạn mã cho thấy lợi ích của nó.)
CẬP NHẬT:
Trong trường hợp
IService myService;// ...
public void doSomething() {
myService.fetchData();
}
Làm cách nào IoC framework có thể đoán được việc triển khai myService nào mà tôi muốn được đưa vào nếu có nhiều hơn một? Nếu chỉ có một lần triển khai của giao diện đã cho và tôi để vùng chứa IoC tự động quyết định sử dụng nó, nó sẽ bị hỏng sau khi lần triển khai thứ hai xuất hiện. Và nếu cố tình chỉ có một giao diện được triển khai thì bạn không cần phải đưa nó vào.
Sẽ thực sự thú vị khi thấy một đoạn cấu hình nhỏ cho IoC cho thấy lợi ích của nó. Tôi đã sử dụng Spring được một thời gian và tôi không thể cung cấp ví dụ như vậy. Và tôi có thể hiển thị các dòng đơn thể hiện lợi ích của hibernate, dwr và các khung công tác khác mà tôi sử dụng.
CẬP NHẬT 2:
Tôi nhận thấy rằng cấu hình IoC có thể được thay đổi mà không cần biên dịch lại. Nó thực sự là một ý tưởng tốt? Tôi có thể hiểu khi ai đó muốn thay đổi thông tin đăng nhập DB mà không cần biên dịch lại - người đó có thể không phải là nhà phát triển. Trong thực tế của bạn, bao lâu một người khác không phải nhà phát triển thay đổi cấu hình IoC? Tôi nghĩ rằng đối với các nhà phát triển không có nỗ lực để biên dịch lại lớp cụ thể đó thay vì thay đổi cấu hình. Và đối với những người không phải nhà phát triển, bạn có thể muốn làm cho cuộc sống của anh ta dễ dàng hơn và cung cấp một số tệp cấu hình đơn giản hơn.
CẬP NHẬT 3:
Cấu hình bên ngoài của ánh xạ giữa các giao diện và triển khai cụ thể của chúng
Điều gì là tốt để làm cho nó mở rộng? Bạn không đặt tất cả mã của mình ra bên ngoài, trong khi bạn chắc chắn có thể - chỉ cần đặt nó vào tệp ClassName.java.txt, đọc và biên dịch theo cách thủ công ngay lập tức - thật tuyệt, bạn đã tránh được việc biên dịch lại. Tại sao nên tránh biên dịch ?!
Bạn tiết kiệm thời gian viết mã vì bạn cung cấp ánh xạ một cách khai báo, không phải trong mã thủ tục
Tôi hiểu rằng đôi khi cách tiếp cận khai báo tiết kiệm thời gian. Ví dụ: tôi chỉ khai báo một lần ánh xạ giữa thuộc tính bean và cột DB và chế độ ngủ đông sử dụng ánh xạ này trong khi tải, lưu, xây dựng SQL dựa trên HSQL, v.v. Đây là nơi phương pháp khai báo hoạt động. Trong trường hợp Spring (trong ví dụ của tôi), khai báo có nhiều dòng hơn và có cùng biểu cảm như mã tương ứng. Nếu có một ví dụ khi khai báo như vậy ngắn hơn mã - tôi muốn xem nó.
Nguyên tắc Inversion of Control cho phép dễ dàng kiểm tra đơn vị vì bạn có thể thay thế các triển khai thực bằng các triển khai giả (như thay thế cơ sở dữ liệu SQL bằng một trong bộ nhớ)
Tôi hiểu sự nghịch đảo của lợi ích kiểm soát (Tôi thích gọi mẫu thiết kế được thảo luận ở đây là Dependency Injection, vì IoC tổng quát hơn - có nhiều loại kiểm soát và chúng tôi chỉ đảo ngược một trong số chúng - kiểm soát khởi tạo). Tôi đã hỏi tại sao ai đó lại cần một thứ gì đó khác ngoài ngôn ngữ lập trình cho nó. Tôi chắc chắn có thể thay thế các triển khai thực bằng các triển khai giả bằng cách sử dụng mã. Và mã này sẽ thể hiện điều tương tự như cấu hình - nó sẽ chỉ khởi tạo các trường có giá trị giả.
mary = new FakeFemale();
Tôi hiểu lợi ích của DI. Tôi không hiểu những lợi ích nào được thêm vào bởi cấu hình XML bên ngoài so với cấu hình mã tương tự. Tôi không nghĩ rằng nên tránh việc biên dịch - tôi biên dịch hàng ngày và tôi vẫn còn sống. Tôi nghĩ rằng cấu hình của DI là một ví dụ xấu về cách tiếp cận khai báo. Khai báo có thể hữu ích nếu được khai báo một lần VÀ được sử dụng nhiều lần theo nhiều cách khác nhau - như hibernate cfg, nơi ánh xạ giữa thuộc tính bean và cột DB được sử dụng để lưu, tải, xây dựng truy vấn tìm kiếm, v.v. Cấu hình Spring DI có thể dễ dàng dịch sang cấu hình mã, giống như trong đầu của câu hỏi này, nó có thể không? Và nó chỉ được sử dụng để khởi tạo bean, phải không? Có nghĩa là một cách tiếp cận khai báo không thêm bất cứ điều gì ở đây, phải không?
Khi tôi khai báo ánh xạ ngủ đông, tôi chỉ cung cấp một số thông tin cho chế độ ngủ đông và nó hoạt động dựa trên thông tin đó - tôi không cho nó biết phải làm gì. Trong trường hợp mùa xuân, tuyên bố của tôi cho biết chính xác mùa xuân phải làm - vậy tại sao phải khai báo, tại sao không chỉ làm?
CẬP NHẬT CUỐI CÙNG: Các bạn
ơi, rất nhiều câu trả lời đang nói với tôi về việc tiêm thuốc phụ thuộc mà tôi BIẾT LÀ TỐT. Câu hỏi là về mục đích của cấu hình DI thay vì khởi tạo mã - Tôi có xu hướng nghĩ rằng việc khởi tạo mã ngắn hơn và rõ ràng hơn. Câu trả lời duy nhất mà tôi nhận được cho đến nay cho câu hỏi của mình là nó tránh biên dịch lại khi cấu hình thay đổi. Tôi đoán tôi nên đăng một câu hỏi khác, bởi vì nó là một bí mật lớn đối với tôi, tại sao việc biên dịch lại nên tránh trong trường hợp này.