2009-02-26 37 views

Trả lời

9

Hãy đọc số tuyệt vời này article từ Martin Fowler.

Ngoài ra, hãy xem wikipedia article.

Dependency Injection là ví dụ nổi tiếng nhất của đảo ngược tầm kiểm soát, mà trong ngắn hạn biến mã của bạn từ này:

public class FileReader { } 
public class Application { 
    // inflexible concrete dependency 
    private FileReader fileReader = new FileReader(); 
} 

Để:

public interface Reader {} 
public class FileReader implements Reader {} 
public class Application { 
    // flexible abstract dependency injected in 
    private Reader reader; 

    public Application(Reader reader) { // constructor injection 
     this.reader = reader; 
    } 
    public void setReader(Reader reader) { // setter injection 
     this.reader = reader; 
    } 
} 
+1

toolkit == quickDraw. – duffymo

+0

(thổi khói từ thùng) – toolkit

+0

huh? là một trò đùa bên trong? –

4

Không, IoC không phải là DDD hoặc TDD .

Martin Fowler's article là một phần giới thiệu tốt.

+0

Đồng ý 100%, nhưng IOC gần như là bắt buộc đối với TDD tốt. ;-) –

+0

Xin lỗi, không đúng chỗ. Có nghĩa là thêm vào câu trả lời khác. –

+0

Không, tôi đã có mặt tại chỗ, vì vậy tôi chỉ thêm ý kiến ​​chứng minh tôi là tổng số dolt hiện nay. –

1

Đối với câu hỏi của bạn về IOC là gì, Wikipedia có số fairly extensive explanation.

Về hướng dẫn hoặc ví dụ this hướng dẫn bao gồm nó khá tốt và có nhiều mã exmaple.

+0

+1, chỉ dành cho báo giá DeMarco. – duffymo

12

IOC hoặc ngược lại kiểm soát, là trong hầu hết các ứng dụng, đảo ngược tuyến đường thông qua mã từ giao diện người dùng đến cơ sở dữ liệu. Si này không phải là một câu trả lời hoàn chỉnh, nhưng nó là một trong những cách dễ nhất để có được đầu của bạn xung quanh khái niệm.

Nếu bạn muốn tìm hiểu IOC, tham gia TDD, vì bạn sẽ thấy việc thiết lập các bài kiểm tra dễ dàng hơn nhiều khi bạn đảo ngược.

Ví dụ:

dòng chảy điển hình của hầu hết các ứng dụng .NET Tôi đã thấy được một cái gì đó như thế này:

UserCollection col = BusinessLayer.Class.GetLoggedInUsers(); 
//Business logic 
return col; 

sau đó kinh doanh là như thế này:

UserTable table = DataLayer.Class.GetLoggedInUsers(); 
return table; 

vv Điều này là tất cả mã giả. Để sử dụng IOC trong ví dụ này, bạn thêm một giao diện cho lớp lớp dữ liệu, như IUserRepository. Bạn có thể sử dụng Generics, và tôi muốn giới thiệu bên dưới mui xe.

Sau đó, bạn có thể làm một cái gì đó như thế này:

IUserRepository repository = SetUpRepository(); 
UserCollection col = BusinessLayer.Class.GetUsers(repository); 

Tại sao điều này lại quan trọng? Để thử nghiệm, bạn có thể tạo một kho lưu trữ giả và đưa nó vào lớp nghiệp vụ. Mô hình chứa dữ liệu luôn giống nhau, có nghĩa là bạn đang thực hiện mã của mình, chứ không phải kiểm tra từ đầu đến cuối.

Nếu bạn muốn C#, đây là một ví dụ cơ bản về weblogs.asp.net:

0

Nếu bạn hiểu DIP (dependancy Inversion Nguyên tắc), IOC là bánh. Tôi khuyên bạn nên học các nguyên tắc hướng đối tượng trước khi bạn học các mẫu. Các nguyên tắc cốt lõi có thể được xếp chồng lên nhau như legos để thực hiện bất kỳ mẫu nào.Brandon Joyce

7

Để nói thuật ngữ, đảo ngược kiểm soát là một mẫu hỗ trợ, trong số những thứ khác, nguyên tắc trách nhiệm duy nhất.

Để hiểu lý do tại sao tất cả điều này hữu ích, bạn cần có một số giải trình để chịu đựng với tôi.

Trách nhiệm duy nhất về cơ bản có nghĩa là lớp học của bạn phải độc lập với các phần khác của hệ thống càng tốt, để giảm thiểu tác động của việc thay đổi một phần này sang phần khác. (Bạn cũng có thể kết nối lại với thực tế là việc thay đổi việc triển khai sẽ không kích hoạt biên dịch lại tất cả các tệp trong các dự án của bạn, ví dụ như trường hợp khi thay đổi các tệp .h trong một dự án C/C++). Tác dụng phụ là bạn kết thúc với rất nhiều vật nhỏ chỉ làm một việc, nhưng rất tốt (trong một thế giới lý tưởng)

Nhưng trong hầu hết các trường hợp, để thực hiện công việc của mình, một đối tượng cần nói chuyện đối tượng khác: nó phụ thuộc vào chúng.

Phần đầu tiên của việc giảm nhẹ là tách riêng việc triển khai khỏi giao diện. Điều đó có nghĩa là dựa vào các giao diện (hoặc các lớp trừu tượng hoàn toàn, tùy thuộc vào ngôn ngữ của bạn lựa chọn), để một đối tượng không gắn với việc thực hiện cụ thể của một đối tượng khác.

Vì vậy, để sử dụng một ví dụ kinh điển, trong những nhu cầu lớp doanh nghiệp, bạn cần phải thực hiện một chức năng mà cần truy cập vào - Các lớp dữ liệu để lấy đối tượng - Một số dịch vụ khác - một logger để đăng nhập thông tin và hay lỗi

Đổi lại, mọi dịch vụ hoặc phụ thuộc đều có các phụ thuộc riêng, mà lớp học của bạn cần phải biết ngay cả khi nó không sử dụng chúng. Tùy thuộc vào số lượng tài liệu tham khảo, việc thiết lập đối tượng có thể nhanh chóng thoát ra khỏi bàn tay. Bây giờ nhân số đó với số lượng các lớp bạn cần để viết và bạn kết thúc với một đống lộn xộn.

Sử dụng thùng chứa IOC về cơ bản giúp bạn thoát khỏi mớ hỗn độn đó. Khi bạn cần một đối tượng, bạn không "làm mới nó". Thay vào đó bạn yêu cầu container IOC để lấy nó cho bạn. Thùng chứa chịu trách nhiệm phân phối một đối tượng chức năng, sẵn sàng để sử dụng, bất kể phụ thuộc của nó.

Điều đó có nghĩa là lớp học của bạn không cần phải nhận thức được sự phụ thuộc của các lớp mà nó dựa vào, điều này sẽ giảm bớt sự rối loạn. Hơn nữa, không cần biết lớp thực tế triển khai dịch vụ dựa trên điều gì, có nghĩa là - Việc triển khai dịch vụ có thể được định nghĩa trong một dự án khác (dll hoặc bất kỳ thứ gì), do đó sửa đổi nó sẽ không bao giờ ảnh hưởng đến bạn lớp có thể là một tùy chọn khác nhau tùy thuộc vào ngữ cảnh (suy nghĩ về việc thay đổi cơ sở dữ liệu hoặc thậm chí truy cập dịch vụ web để truy xuất thông tin tùy thuộc vào cấu hình hoặc trạng thái hiện tại của ứng dụng).

Để thử và trả lời các câu hỏi khác của bạn, IOC là một mẫu. TDD và DDD là phương pháp thiết kế, do đó người ta không thể đánh đồng phương pháp khác. Nhưng IOC là một công cụ vô giá để hỗ trợ TDD hoặc DDD.

Tôi biết súp viết tắt và các phần mẫu bạn có thể tìm thấy xung quanh không dễ bị lúng túng. Lời khuyên tốt nhất tôi có thể cung cấp cho bạn là thử một số dự án nhỏ ở bên cạnh, các nguyên mẫu mà bạn S d mương, chỉ để có được sự xử lý trên những thứ đó. Không phải là một cách dễ dàng để đi nếu bạn đang tìm kiếm điều đó cho công việc, nhưng hoàn toàn xứng đáng với nó, nếu chỉ từ quan điểm cá nhân.

Hy vọng rằng sẽ giúp ích một chút.

0

Inversion of Control là sự trừu tượng hóa cấu trúc của logic. Một cách tiếp cận (thường được sử dụng đồng nghĩa với IoC) là Dependency Injection, nó tóm tắt các tham chiếu giữa các đối tượng. Khi các đối tượng được giải phóng khỏi các chi tiết thực hiện của ứng dụng, chẳng hạn như lớp nào thực hiện dịch vụ nào, chúng được tự do tập trung vào các chức năng cốt lõi của chúng. Ví dụ:

Ví dụ: giả sử bạn có một lớp cần bản đồ Foo đối tượng cho các đối tượng Bar. Bạn có thể viết này:

public class FooMapper 
{ 
    public Bar Map(Foo foo) 
    { 
     // ... 
    } 
} 

và sử dụng nó như thế này:

public class NeedsToMapFoos 
{ 
    public void MapSomeFoos() 
    { 
     var fooMapper = new FooMapper(); 

     // ... 
    } 
} 

Trong khi hợp lệ, đây cũng là cứng nhắc. NeedsToMapFoos chỉ quan tâm rằng ánh xạ xảy ra, không phải là nó xảy ra theo bất kỳ cách cụ thể nào.

Chúng ta có thể đại diện cho khái niệm "thực hiện sans hoạt động" với một giao diện:

public interface IFooMapper 
{ 
    Bar Map(Foo foo); 
} 

và tuyên bố một sự phụ thuộc vào hoạt động mà:

public class NeedsToMapFoos 
{ 
    private readonly IFooMapper _fooMapper; 

    public NeedsToMapFoos(IFooMapper fooMapper) 
    { 
     _fooMapper = fooMapper; 
    } 

    public void MapSomeFoos() 
    { 
     // ...use _fooMapper... 
    } 
} 

Bây giờ NeedsToMapFoos còn ít kiến ​​thức, có nghĩa là nó ít phức tạp hơn. Thay vì thực hiện các nhiệm vụ hành chính, bạn có thể tự do tập trung vào trường hợp kinh doanh.

Các đối tượng được tính toán tốt như thế này cũng dễ thích nghi hơn. Cũng giống như kim cương cứng và đất sét dễ uốn, cấu trúc bên trong xác định phản ứng thay đổi.

Cuối cùng, logic được viết theo kiểu này cũng linh hoạt. Giả sử FooMapper.Map là một hoạt động tốn kém và phải được lưu trong bộ nhớ cache. Bạn có thể sử dụng mẫu trang trí để bao bọc việc triển khai hiện tại và liên tục chuyển nó đến NeedsToMapFoos:

public class CachingFooMapper : IFooMapper 
{ 
    private readonly IFooMapper _innerMapper; 
    private readonly IDictionary<Foo, Bar> _cache; 

    public CachingFooMapper(IFooMapper innerMapper) 
    { 
     _innerMapper = innerMapper; 
    } 

    public Bar Map(Foo foo) 
    { 
     // Read bar from _cache. If not there, read from inner mapper and add to _cache. 
    } 
} 

// Usage 

new NeedsToMapFoos(new CachingFooMapper(new FooMapper())); 
Các vấn đề liên quan