Ok, vì vậy ngày hôm qua chúng tôi đã có một cuộc nói chuyện lớn với những người khác từ cộng đồng Magento liên quan đến việc sử dụng trực tiếp các ObjectManager
lớp / mẫu .
Tôi đã nhận thức được lý do tại sao chúng ta không nên sử dụng ObjectManager trực tiếp, trích dẫn Alan Kent :
Có một số lý do. Mã sẽ hoạt động, nhưng tốt nhất là không tham chiếu trực tiếp lớp ObjectManager.
- Bởi vì chúng tôi nói như vậy! ;-) (được biểu thị tốt hơn dưới dạng mã nhất quán là mã tốt)
- Mã này có thể được sử dụng với khung tiêm phụ thuộc khác trong tương lai
- Việc kiểm tra dễ dàng hơn - bạn chuyển các đối số giả cho lớp được yêu cầu mà không phải cung cấp Trình quản lý đối tượng giả
- Nó giữ cho các phụ thuộc rõ ràng hơn - rõ ràng những gì mã phụ thuộc vào thông qua danh sách hàm tạo, thay vì có các phụ thuộc ẩn ở giữa mã
- Nó khuyến khích các lập trình viên suy nghĩ về các khái niệm như đóng gói và mô đun hóa tốt hơn - nếu hàm tạo trở nên lớn, có thể đó là dấu hiệu mã cần tái cấu trúc
Từ những gì tôi đã thấy trong StackExchange, rất nhiều người có xu hướng tìm kiếm giải pháp dễ / ngắn / không được đề xuất, ví dụ như một cái gì đó như thế này:
<?php
//Get Object Manager Instance
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
//Load product by product id
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($id);
Thay vì trải qua quá trình đau đớn nhưng được khuyến nghị :
- tạo ra một mô-đun
- tuyên bố ưu đãi
- phụ thuộc tiêm
- tuyên bố một phương thức công khai
Tuy nhiên, và ở đây tiến thoái lưỡng nan, các tệp lõi Magento 2 thường gọi trực tiếp cho ObjectManager . Một ví dụ nhanh có thể được tìm thấy ở đây: https://github.com/magento/magento2/blob/develop/app/code/Magento/GoogleOptimizer/Block/Adminhtml/Form.php#L57
Vì vậy, đây là những câu hỏi của tôi:
- Tại sao Magento làm những gì họ khuyên chúng ta không nên làm? Điều đó có nghĩa là có một số trường hợp chúng ta nên sử dụng
ObjectManager
trực tiếp ? Nếu vậy, những trường hợp đó là gì? - Là gì hậu quả của việc sử dụng các ObjectManager trực tiếp ?
The intent of zend-servicemanager is for use as an Inversion of Control container. It was never intended as a general purpose service locator [...]
. Mà nó áp dụng cho M2, quá. Cũng kiểm tra There are valid use cases
phần, một lần nữa, áp dụng ở đây, quá.