Dường như có rất nhiều nhầm lẫn về mẫu Inversion of Control (IoC). Một số người đã đánh đồng nó với Mô hình chiến lược hoặc Mô hình thành phần, nhưng những so sánh này không thực sự nắm bắt được IoC là gì. IoC thực sự là về cách thu được một sự phụ thuộc. Tôi sẽ cho bạn một ví dụ:
class Game {
void Load() {
this.Sprite.Load(); // loads resource for drawing later
}
}
class Sprite {
void Load() {
FileReader reader = new FileReader("path/to/resource.gif");
// load image from file
}
}
Ở trên, rõ ràng Sprite.Load
có sự phụ thuộc vào a FileReader
. Khi bạn muốn kiểm tra phương pháp bạn cần như sau:
- Một hệ thống tập tin tại chỗ
- Một tệp thử nghiệm để tải từ hệ thống tệp
- Khả năng kích hoạt các lỗi hệ thống tệp phổ biến
Hai cái đầu tiên là rõ ràng, nhưng nếu bạn muốn đảm bảo rằng việc xử lý lỗi của bạn hoạt động như mong đợi, bạn cũng thực sự cần số 3. Trong cả hai trường hợp, bạn có khả năng làm chậm các bài kiểm tra của mình xuống một chút vì bây giờ chúng cần phải vào đĩa và bạn có thể làm cho môi trường kiểm tra của bạn phức tạp hơn.
Mục tiêu của IoC là tách rời việc sử dụng hành vi từ việc xây dựng nó. Lưu ý cách này khác với mẫu Chiến lược. Với mẫu Chiến lược, mục tiêu là gói gọn một đoạn hành vi có thể sử dụng lại để bạn có thể dễ dàng mở rộng nó trong tương lai; nó không có gì để nói về cách các chiến lược được xây dựng.
Nếu chúng ta viết lại Sprite.Load
phương thức trên, chúng ta có thể sẽ kết thúc bằng:
class Sprite {
void Load(IReader reader) {
// load image through reader
}
}
Bây giờ, chúng tôi đã tách rời việc xây dựng của người đọc từ việc sử dụng nó. Do đó, có thể trao đổi trong một trình đọc thử trong khi thử nghiệm. Điều này có nghĩa là môi trường kiểm tra của bạn không còn cần một hệ thống tệp, tệp kiểm tra và có thể dễ dàng mô phỏng các sự kiện lỗi.
Lưu ý rằng tôi đã làm hai điều trong bản viết lại của mình. Tôi đã tạo một giao diện IReader
gói gọn một số hành vi - tức là đã triển khai mẫu Chiến lược. Ngoài ra, tôi chuyển trách nhiệm tạo độc giả phù hợp sang một lớp khác.
Có lẽ chúng ta không cần một tên mẫu mới để mô tả ở trên. Nó tạo cho tôi một sự pha trộn giữa các mẫu Chiến lược và Nhà máy (đối với các thùng chứa IoC). Điều đó đang được nói, tôi không chắc chắn về lý do mọi người phản đối mô hình này vì rõ ràng nó giải quyết được một vấn đề thực sự và chắc chắn, đối với tôi điều này không rõ ràng với Java.