Tôi đang thiết kế một hệ thống mới và tôi muốn biết điều khiển đảo ngược (IOC) là gì và quan trọng hơn là khi nào nên sử dụng nó.
Nó có phải được thực hiện với các giao diện hoặc có thể được thực hiện với các lớp không?
Tôi đang thiết kế một hệ thống mới và tôi muốn biết điều khiển đảo ngược (IOC) là gì và quan trọng hơn là khi nào nên sử dụng nó.
Nó có phải được thực hiện với các giao diện hoặc có thể được thực hiện với các lớp không?
Câu trả lời:
IoC (xem Inversion of Control trên Wikipedia) có thể áp dụng trong trường hợp một thành phần không thể thực hiện một nhiệm vụ hoàn toàn vì nó không có một số thông tin hoặc chức năng cần thiết.
Ví dụ đơn giản nhất về mẫu IoC sẽ là các hàm gọi lại trong C. Ví dụ: bạn có thể khai báo hàm:
void Iterator(void *list, Func* f)
Lặp đi lặp lại list
việc áp dụng f
chức năng cho từng mục của nó. Các Iterator
chức năng không biết làm thế nào mỗi mục sẽ được xử lý, bạn chỉ cần cung cấp một chức năng như một cuộc tranh cãi, và nó xử lý chúng.
Như ví dụ trước đây cho thấy, IoC cho phép bạn tách chương trình của bạn thành các thành phần riêng biệt không biết về nhau. Một trong những phiên bản phổ biến nhất của IoC là Dependecy Injection .
Trong Dependency Injection, mỗi thành phần phải khai báo một danh sách các phụ thuộc cần thiết để thực hiện nhiệm vụ của nó. Trong thời gian chạy, một thành phần đặc biệt (thường) được gọi là IoC Container thực hiện liên kết giữa các thành phần này. Nó cố gắng cung cấp các giá trị cho các phụ thuộc thành phần được công bố.
Đây là một ví dụ trong mã giả:
class Foo
{
<Require Boo>Constructor(Boo boo){ boo.DoSomething }
}
Trong ví dụ này, lớp Foo
có một hàm tạo yêu cầu đối số kiểu Boo
để thực hiện một số hành động.
Bạn có thể tạo một thể hiện của lớp Foo
bằng mã tương tự như sau:
MyContainer.Create(typeof Foo)
MyContainer
- là một IoC Container , đảm nhiệm việc lấy ví dụ Boo
và chuyển nó đến hàm Foo
tạo.
Tóm lại, IoC cho phép bạn tách chương trình của bạn thành các phần riêng biệt. Điều này là tốt bởi vì:
Tuy nhiên, trong một số trường hợp, IoC có thể khiến mã khó hiểu hơn.
Nếu bạn muốn xem ví dụ hay về việc sử dụng IoC trong thế giới thực , hãy xem Khối ứng dụng UI hỗn hợp Mircosoft và CompositeWPF
Tôi hy vọng lời giải thích của tôi giúp bạn.
Trân trọng,
aku
Vì tôi đã tự mình tìm hiểu điều này gần đây và giữ tất cả các dấu trang, nên sau đây tôi thấy vô giá khi tìm hiểu về IOC / DI.
Martin Fowlers Bài viết gốc về IOC / DI
Một số khái niệm cần biết trước
Một bộ sưu tập tuyệt vời các hướng dẫn IOC / DI
Sách trên IOC / DI từ Manning Press
Nguồn và Giải thích về cách tạo IOC của riêng bạn - Nguyên nhân đọc mã nguồn luôn là cách tốt nhất để hiểu một khái niệm.
Xin chào JMS, về cơ bản IoC / DI sẽ cho phép bạn xác định việc triển khai nào bạn đang sử dụng một lần và giữ một bản sao tĩnh của vùng chứa của bạn để tham chiếu mỗi khi bạn muốn tham chiếu nó.
Wikipedia có thể sẽ giúp bạn, nhưng tôi muốn tham khảo phần thứ hai của bạn - vâng, việc tiêm phụ thuộc có thể được thực hiện cho các lớp (nghĩa là mỗi khi loại lớp này cần được truyền vào một phương thức, hãy sử dụng lớp này), nhưng tốt hơn là sử dụng các giao diện, bởi vì theo cách đó bạn có thể thay đổi phiên bản của nhà cung cấp, kho lưu trữ, v.v. bạn đang sử dụng chỉ bằng cách tham chiếu lại nó trong thiết lập của mình.
IE, giả sử bạn đã có một giao diện để đọc một luồng và bạn đã có một triển khai XMLStreamReader và SQLStreamReader. Sau đó, bạn có thể chuyển tham chiếu đến giao diện cho các phương thức của mình và sau đó trong bộ chứa IoC của bạn cho nó biết cái nào sẽ sử dụng.
Vì vậy, bạn có thể có Danh sách công khai ReadP People (trình đọc IStreamReader) và trong thiết lập của bạn cho bộ chứa IoC của bạn, hãy nói với nó, mỗi khi bạn mong đợi IStreamReader sử dụng SQLStreamReader.
Sau đó, nếu bạn đổi ý sau này, bạn chỉ cần thay đổi nó ở một nơi (thiết lập vùng chứa của bạn) và sẽ không có vấn đề bao nhiêu phương thức yêu cầu IStreamReader, nó sẽ luôn nhận được mặc định mà bạn đã nói với container của mình phục vụ lên
Giả sử bạn có trình xác nhận để kiểm tra xem một doanh nghiệp có hợp lệ trong hệ thống của bạn hay không. "BusinessValidator" của bạn có thể có trường loại Địa chỉ xác thực, xác thực phần địa chỉ của doanh nghiệp. Nếu bạn muốn kiểm tra BusinessValidator mà không thực thi mã bên ngoài (tức là mã addressValidator) thì nếu bạn đã sử dụng một số loại IoC / DI trong khung của mình, bạn có thể dễ dàng "tiêm" một mock addressValidator vào đó và không phải lo lắng về việc thử nghiệm mã ngoài phạm vi của lớp đang thử nghiệm.