2010-08-02 33 views

Trả lời

11

Vâng, tạo đối tượng mới rõ ràng như nó có thể nhận được - bạn tạo một phiên bản mới của lớp mong muốn.

Tiêm phụ thuộc là cơ chế cung cấp cho bạn các tài liệu tham khảo mà bạn cần chúng. Hãy tưởng tượng một lớp đại diện cho một nhóm kết nối đến cơ sở dữ liệu của bạn - bạn thường chỉ có một cá thể của lớp đó. Bây giờ bạn cần phân phối tham chiếu đến tất cả các lớp sử dụng nó. Đây là nơi Dependency Injection có ích - bằng cách sử dụng một khung công tác DI như Spring bạn có thể định nghĩa rằng một cá thể của nhóm của bạn sẽ được tiêm vào các lớp cần nó.

Câu hỏi của bạn không dễ trả lời vì việc tạo đối tượng và tiêm phụ thuộc không thể so sánh dễ dàng ...

+2

Điều này khác với việc sử dụng Singleton như thế nào? – Radu

+0

@Radu a Singleton là mẫu thiết kế hạn chế số lượng phiên bản của một lớp cụ thể đến tối đa một lớp. Vì vậy, việc tạo ra cá thể là một phần của việc thực hiện mẫu. Các singleton không được tiêm vào những nơi mà bạn cần nó, đó là những gì bạn cần tiêm phụ thuộc cho. – f1sh

+1

Làm thế nào là trường hợp duy nhất của lớp đó được "kỳ diệu" instanced và phân phối tốt hơn so với gọi một SingletonClass.getSingleInstance() là câu hỏi của tôi. Việc tiêm phụ thuộc này trông có vẻ dư thừa đối với tôi nếu bạn chỉ có 1 thể hiện, chỉ cần sử dụng mẫu đơn. – Radu

2

Khi sử dụng vùng chứa kiểm soát đảo ngược để thực hiện tiêm phụ thuộc, vùng chứa sẽ tạo đối tượng chứ không phải nhà phát triển. Điều này được thực hiện để container có thể "tiêm" các đối tượng này vào các đối tượng khác.

Tôi khuyên bạn nên đọc một số bài viết về tiêm phụ thuộc và/hoặc mùa xuân. Hoặc đọc các chủ đề khác về tiêm phụ thuộc tại đây trên SO.

+0

đề xuất một số liên kết .. – TaherT

13

Tất nhiên cả tạo đối tượng. Sự khác biệt là ở ai chịu trách nhiệm tạo ra. Nó có phải là lớp cần các phụ thuộc của nó hay một thùng chứa như Spring chẳng hạn, mà nó phụ thuộc vào các thành phần phụ thuộc. Bạn cấu hình các phụ thuộc trong một tệp cấu hình riêng (thường là XML).

Nó thực sự là một sự phân tách mối quan tâm. Lớp học nói rằng tôi cần cái này, cái này và thành phần này để tôi hoạt động đúng. Lớp học không quan tâm làm thế nào nó được các thành phần của nó. Bạn cắm chúng vào lớp với một tệp cấu hình riêng biệt.

Để cung cấp cho bạn ví dụ, hãy cân nhắc việc có một lớp mua sắm cần mô-đun thanh toán. Bạn không muốn mã hóa mô-đun thanh toán nào sẽ được sử dụng. Để đạt được điều này, bạn nghịch đảo sự kiểm soát. Bạn có thể thay đổi mô-đun thanh toán đã sử dụng bằng một vài thao tác gõ phím trong tệp cấu hình của vùng chứa. Sức mạnh là bạn không chạm vào bất kỳ mã Java nào.

9

Vâng, chúng không chính xác so sánh được. Bạn sẽ luôn phải tạo một đối tượng mới bằng cách khởi tạo một lớp tại một số điểm. Dependency injection cũng yêu cầu tạo các đối tượng mới.

Tiêm phụ thuộc thực sự có hiệu lực khi bạn muốn kiểm soát hoặc xác minh hành vi của các trường hợp được sử dụng bởi một lớp mà bạn sử dụng hoặc muốn kiểm tra. (Đối với tiêm phụ thuộc phát triển thử nghiệm là chìa khóa cho bất kỳ ngoại trừ ví dụ nhỏ nhất).

Giả sử một Chủ lớp yêu cầu đối tượng của lớp Xử lý. Cách truyền thống để thực hiện điều đó là để cho cá thể Chủ sở hữu tạo và sở hữu nó:

class Holder { 
    private Handle myHandle = new Handle(); 
    public void handleIt() { 
     handle.handleIt(); 
    } 
} 

Trường hợp Chủ tạo myHandle và không ai ngoài lớp học có thể nhận được nó. Trong một số trường hợp, unittesting được trên của họ, đây là một vấn đề bởi vì nó không thể kiểm tra lớp Holder mà không tạo ra dụ xử lý mà lần lượt có thể phụ thuộc vào nhiều lớp khác và các trường hợp. Điều này làm cho thử nghiệm khó sử dụng và cồng kềnh.

Bằng cách tiêm đối tượng Xử lý, ví dụ trong hàm tạo, một người nào đó từ bên ngoài chịu trách nhiệm về việc tạo cá thể.

class Holder { 
    private Handle myHandle; 

    public Holder(Handle injectedHandle) { 
     myHandle = injectedHandle; 
    } 

    public void handleIt() { 
     handle.handleIt(); 
    } 
} 

Như bạn có thể thấy mã gần như giống nhau và xử lý vẫn là riêng tư, nhưng lớp Chủ bây giờ có nhiều khớp nối thua với thế giới bên ngoài của nó. Và khi kiểm tra lớp Chủ, một đối tượng giả hoặc sơ đồ có thể được tiêm thay vì một thực thể làm cho nó có thể xác minh hoặc kiểm soát sự tương tác giữa Holder, người gọi và tay cầm của nó.

Việc tiêm thực tế sẽ diễn ra ở một số nơi khác, thường là một số chương trình "chính". Có rất nhiều các khuôn khổ có thể giúp bạn làm điều đó mà không cần lập trình, nhưng thực chất đây là mã trong chương trình "chính":

... 
private Handle myHandle = new Handle(); // Create the instance to inject 
private Handler theHandler = new Handler(myHandle); // Inject the handle 
... 

Về bản chất, việc tiêm là gì khác hơn là một phương pháp ưa thích set. Và tất nhiên, bạn có thể thực hiện cơ chế tiêm bằng cách sử dụng thay vì trong hàm tạo như ví dụ đơn giản ở trên.

+0

Tôi chỉ cần đăng nhập để upvote này, đó là cách tốt hơn so với anwser chấp nhận và giải thích điều là một cách thích hợp. – Anearion

+0

Nhưng cách 'injectedHandle' được bắt đầu ngoài tầm kiểm soát của chúng ta khi chúng ta tạo một' Chủ'? Điều gì sẽ xảy ra nếu có nhiều tham số hơn, làm thế nào để biết cách khởi tạo chúng, hoặc không khởi tạo? – Yoda

+0

@Yoda, đã thêm mô tả về cách thực hiện tiêm thực tế. Hy vọng rằng sẽ giúp. – thoni56

1

Chèn phụ thuộc sẽ thêm một lớp cấu hình vào ứng dụng của bạn. Trong ý nghĩa, khi bạn xây dựng đối tượng mã cứng, bạn cần phải xây dựng lại và triển khai lại ứng dụng của mình, nhưng khi bạn sử dụng tiêm phụ thuộc, bạn có thể định cấu hình XML và thay đổi hành vi mà không cần xây dựng lại và triển khai lại. Có rất nhiều trường hợp sử dụng, nơi điều này có thể tiết kiệm rất nhiều cà vạt và công sức.

Các vấn đề liên quan