Ví dụ người trợ giúp Magento 2


11

Khi tôi nghĩ rằng tôi đã quấn đầu quanh hệ thống DI từ Magento 2, một cái gì đó xuất hiện và hủy kết thúc nó.
Tôi thấy trong mã lõi các cách khác nhau để truy cập một người trợ giúp.
Ví dụ trong Magento\Catalog\Controller\Category::_initCategoryđó là:

if (!$this->_objectManager->get('Magento\Catalog\Helper\Category')->canShow($category)) {
    return false;
}

Nhưng trong Magento\Catalog\Block\Category\Viewhelper được tiêm int anh constructor

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Catalog\Model\Layer\Category $catalogLayer,
    \Magento\Framework\Registry $registry,
    \Magento\Catalog\Helper\Category $categoryHelper,
    array $data = array()
) {
    $this->_categoryHelper = $categoryHelper;
    $this->_catalogLayer = $catalogLayer;
    $this->_coreRegistry = $registry;
    parent::__construct($context, $data);
}

Điều này khiến tôi nghĩ rằng những người trợ giúp nên được truy cập khác nhau trong các bộ điều khiển và khối (và mô hình) nhưng sau đó tôi tìm thấy một bộ điều khiển trong đó một trình trợ giúp được đưa vào trong hàm tạo Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute.

Xin hãy xóa sương mù cho tôi.
Khi nào tôi nên sử dụng DI và khi nào nên sử dụng objectManager? và tại sao?
Tôi đã đọc câu hỏi này: Người trợ giúp tức thì trong Magento 2 . Đây chỉ là một câu hỏi tiếp theo về điều đó.

Câu trả lời:


10

Tôi thích DI hơn nếu có thể, vì sử dụng trình quản lý đối tượng đã vi phạm luật pháp của demeter. Khi sử dụng trình quản lý đối tượng, các phụ thuộc này chỉ được ẩn trong logic phương thức.


Vâng. Tôi đồng ý. Tôi sẽ sử dụng DI, nhưng tôi tò mò tại sao điều này được thực hiện trong lõi? Có lẽ ai đó đã không được cấu trúc lại các lớp tôi đã đề cập chưa?
Marius

Afaik họ vẫn tái cấu trúc rất nhiều và hy vọng họ cũng sẽ chạm vào những nơi này. Nhưng cũng không biết về các ưu tiên phải tồn tại nếu họ muốn thực sự phát hành vào một lúc nào đó. Vì vậy, có thể một số tính năng mới hoặc thực tiễn xấu khác sẽ được khắc phục trước tiên.
Tobias

Điều gì nếu bạn có lớp 10 chức năng và CHỈ 1 chức năng yêu cầu mô hình cụ thể? Sẽ không dư thừa (từ chế độ xem hiệu suất) để tải mô hình thông qua hàm xây dựng cho mỗi 10 hàm trong khi chúng ta có thể tải nó bằng trình quản lý đối tượng chỉ trong 1 hàm duy nhất?
JohnyFree

6

Tôi không biết nhiều về việc triển khai Magento, nhưng có vẻ như đó ObjectManagerTrình định vị dịch vụ .

Nói chung, việc sử dụng Trình định vị dịch vụ để truy cập các phụ thuộc trong một đối tượng là khá tệ, hãy xem bài viết này .

Xác định rõ ràng sự phụ thuộc của bạn thông qua một nhà xây dựng là một cách tiếp cận tốt hơn nhiều. Nó hỗ trợ kiểm tra đơn vị và chạy các vấn đề thời gian với các dịch vụ không được xác định.

Việc tiêm Trình quản lý đối tượng vào một lớp về cơ bản là tiêm một Sổ đăng ký vào lớp của bạn có quyền truy cập vào tất cả các dịch vụ ứng dụng của bạn, điều này rõ ràng là không đúng.

Tôi sử dụng ZF2 một chút công bằng và thường định nghĩa các lớp xuất xưởng nhỏ cho Dịch vụ, Bộ điều khiển và bất kỳ lớp nào yêu cầu phụ thuộc. Các lớp nhà máy này có quyền truy cập vào Trình định vị dịch vụ và lấy tất cả các dịch vụ mà đối tượng phụ thuộc và tiêm chúng thông qua hàm tạo. Sử dụng Bộ định vị dịch vụ trong lớp Factory là tốt vì nó chủ yếu là vứt bỏ mã, ví dụ như thế này .

Những nhà máy này vẫn dễ dàng để kiểm tra .

IMO, Sử dụng tiêm constructor bất cứ khi nào có thể. Một lần nữa, tôi không biết quá nhiều về việc triển khai Magento và nếu nó có khái niệm về các nhà máy, từ cái nhìn nhanh, có vẻ như nó hỗ trợ chúng, nhưng xác định rõ ràng các lớp của bạn và sử dụng Trình định vị dịch vụ để xây dựng chúng trong các lớp Factory là một cách tiếp cận sạch sẽ hơn nhiều.

Đây là từ một người bị hạn chế tiếp xúc với các patters đã đề cập ở trên, vì vậy tôi cũng muốn nghe những suy nghĩ / kinh nghiệm của người khác về vấn đề này!

Đọc thêm


Cảm ơn lời giải thích tốt đẹp. Câu hỏi của tôi là "Tại sao có 2 cách để truy cập một người trợ giúp trong lõi?" Vì vậy, đây là một chút lạc đề nhưng nó đã xóa một số nghi ngờ khác mà tôi có. :) Cảm ơn.
Marius

Tôi có lẽ sẽ nói rằng đó chỉ là một thứ chưa được tái cấu trúc. Hoặc đó hoặc có thể là một điều dễ sử dụng. Yêu cầu người tiêu dùng luôn tiêm tất cả các phụ thuộc của họ vào Bộ điều khiển có thể được coi là phản tác dụng, đặc biệt là khi thực hiện RAD. Cung cấp cho người tiêu dùng cả hai cách để truy cập các phụ thuộc sẽ cho phép tiếp cận RAD nhưng vẫn cho phép người khác xác định rõ ràng các phụ thuộc của họ nếu họ muốn.
Aydin Hassan

5

Một cách khác để sử dụng trình trợ giúp (trong mẫu) là:

$this->helper('[Vendor]\[Module]\Helper\[Helper Name]')->getMethodName();

Tôi hy vọng nó hữu ích nếu bạn chưa biết.


điều này tương tự như sử dụng trình quản lý đối tượng. Không chắc đó là ý tưởng tốt nhất.
Marius

1
Phương pháp trên chỉ dành cho các mẫu theo như tôi biết. Trình quản lý đối tượng được sử dụng trong bộ điều khiển, khối, mô hình, v.v.
rbncha

1
Nó không ở trong cùng một sân bóng như mã vì không có phụ thuộc mã vào các mẫu. Các mẫu chỉ là người tiêu dùng và không gây ô nhiễm cho bất kỳ khách hàng nào bị đóng gói bị hỏng.
demkoryu

Tôi không biết Devilkoryu đang cố nói gì. Nhưng cách tốt nhất để gọi bất kỳ người trợ giúp mô-đun là đây. Đây là Magento. Như họ nói, mỗi mã khối / phần được dự định có thể gọi / sửa đổi mà không cần chạm vào lõi. Vì vậy, mọi thứ đều liên quan đến nhau hoặc có sự phụ thuộc.
rbncha

2

Mặc dù đó là câu hỏi cũ, tôi không chắc liệu Marius có câu trả lời hay không. Tôi tin rằng Marius có thể trả lời nó tốt hơn. Tôi muốn trả lời ngắn gọn. Tại sao Magento 2 đề nghị sử dụng DI thay vì trợ giúp?

  • Làm cho sự cô lập trong kiểm tra đơn vị có thể / dễ dàng
  • Xác định rõ ràng sự phụ thuộc của một lớp
  • Tạo điều kiện thiết kế tốt (ví dụ nguyên tắc trách nhiệm (SRP))
  • Sử dụng DI trong mô-đun của bạn giúp giảm nguy cơ lỗi không tương thích khi Magento thay đổi triển khai cơ bản của các giao diện đó. Đây là một khái niệm quan trọng để hiểu cho các nhà phát triển mở rộng.

Tại sao lõi M2 có thể không sử dụng DI trong một số trường hợp?

  • Giảm số lượng lớp học
  • Không tạo ra các giao diện không cần thiết
  • Không có nguy cơ lỗi không tương thích

Mặc dù mô-đun danh mục Core đã được sử dụng trợ giúp, nhưng nó đã sử dụng DI rộng rãi. Trong nghiên cứu của mình, tôi thấy Magento 2 đã sử dụng một vài chức năng trong các tệp trợ giúp của Danh mục lõi không phù hợp với Hợp đồng dịch vụ.

Nếu bạn phải sử dụng rõ ràng một lớp do Magento định nghĩa (chẳng hạn như \ Magento \ Catalog \ Model \ Product), hãy làm rõ sự phụ thuộc ngầm bằng cách phụ thuộc vào việc triển khai cụ thể thay vì giao diện hợp đồng dịch vụ.

Không còn nghi ngờ gì nữa, nhà phát triển tiện ích mở rộng nên sử dụng DI thay vì Magento1 như Helper. Khi thực hiện theo hướng dẫn của Magento 2, bụi phóng xạ bị hạn chế. Khi phá vỡ khuyến nghị, vấn đề xảy ra.


Vâng, tôi đã có câu trả lời của mình trong khi chờ đợi. Nhưng cảm ơn vì đã dành thời gian để trả lời. Đây là thông tin có giá trị cho những người tìm kiếm trực tuyến này.
Marius
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.