Có bao giờ một lý do để thích $ model-> load () hơn các hợp đồng dịch vụ không?


24

Tôi hiểu rằng cách ưa thích để làm việc giữa các mô-đun trong Magento 2 là sử dụng hợp đồng dịch vụ.

Vì vậy, nếu tôi muốn tải một sản phẩm, tôi sử dụng kho sản phẩm:

$product = $productRepository->getById($id);

đó là bằng hợp đồng trả lại một ví dụ của Magento\Catalog\Api\Data\ProductInterface.

Nhưng tôi cũng có thể sử dụng cách cũ thay vào đó, gọi trực tiếp lớp miền:

$product = $productFactory->create()->load($id);

Có trường hợp nào điều này là cần thiết hoặc hữu ích?

Các devdocs nói (tô sáng thêm):

Một mô-đun có thể gọi trực tiếp vào một mô-đun khác. Giải pháp kết hợp chặt chẽ này không được khuyến nghị cho hầu hết các tình huống, nhưng đôi khi không thể tránh khỏi .

[...]

Chiến lược của bạn để gọi mã lớp miền của mô-đun khác phụ thuộc nhiều vào cấu hình và nhu cầu duy nhất của hệ thống của bạn.

Nguồn: http://devdocs.magento.com/guides/v2.0/arch architecture / archi_perspectives / domain_layer.html

Và một nhận xét về một câu hỏi liên quan đã nêu:

sử dụng Kho lưu trữ sẽ cung cấp cho bạn một mô hình dữ liệu Sản phẩm ( Api/Data/Product), đó là mô hình Sản phẩm được chuyển đổi thành DTO bị câm. Một cái gì đó để xem xét, vì chúng khá khác nhau

Nhưng theo như tôi có thể thấy các đối tượng đều giống nhau trong điều kiện bình thường, chỉ có các kiểu trả về trên mỗi phpDoc khác nhau ( Magento\Catalog\Api\Data\ProductInterface/ Magento\Catalog\Model\Product)

Câu trả lời:


23

Lý do để sử dụng ProductRepository's get/ getByIdthay vì một ProductFatory load()phương pháp, là vì trước đây là của một mức độ cao hơn sau này.

A ProductRepository- giống như một ProductFactory- có thể trả về một Product mô hình , nhưng đó không phải là điều M2 muốn bạn xem xét. Đó là không\Magento\Catalog\Api\ProductRepositoryInterface::getById()'s khối doc nói. Nó nói @return \Magento\Catalog\Api\Data\ProductInterface, đó là một giao diện mà một mô hình Sản phẩm đang triển khai.

Vì vậy, bạn nên sử dụng lớp API bất cứ khi nào có thể, bởi vì:

  • Api/Data lớp cũng được sử dụng trong Api Web
  • các mô hình có thể - và có thể sẽ - được tái cấu trúc tại một số điểm; Api/Data/Productsẽ không.
  • Để có được một sản phẩm trong các lớp học của bạn, bạn cần phải tiêm một nhà máy cụ thể ( ProductFactory) hoặc một giao diện ( ProductRepository). Tôi không nghĩ rằng bạn muốn mô-đun của bạn dựa vào bất cứ thứ gì ngoại trừ một giao diện. Do đó tôi không đồng ý với loại tiêm này .

Tôi coi nó chỉ là một lớp trừu tượng nhỏ khác trên các mô hình, để phục vụ cho API Web (REST, SOAP, v.v.).

Trích dẫn câu trả lời này :

Hy vọng, bạn sẽ thích hợp đồng dịch vụ khi mô-đun tùy chỉnh của bạn sẽ không bị phá vỡ sau các phiên bản tiếp theo của Magento 2 (tất nhiên nếu bạn không bỏ qua hợp đồng dịch vụ và sử dụng trực tiếp mô hình / bộ sưu tập / mô hình tài nguyên). Và khi bạn bắt đầu tiêu thụ / tiết lộ API web Magento 2, giờ đây dựa trên cùng các hợp đồng dịch vụ. Vì vậy, bạn phải thực hiện thay đổi chỉ ở một nơi (ví dụ: thông qua plugin) và chúng sẽ được áp dụng ở mọi nơi. Điều này là không thể trong Magento 1.


Không chính xác những gì tôi đã yêu cầu nhưng đó cũng là những gì tôi nghĩ, cảm ơn vì đã xác nhận!
Fabian Schmengler

1
But I could also use the old way instead, calling the domain layer directly: (use factory). Is there any case where this would be necessary or useful?. Có: khi bạn cần gọi phương thức của mô hình chứ không phải phương thức Api/Data/Product. Tốt hơn chưa? :)
nevvermind

Vâng, điều đó có ý nghĩa :)
Fabian Schmengler

14

Đối với tôi, không có lý do để sử dụng loadphương thức trên getById/ getphương thức.

Tôi không nói rằng tôi đúng nhưng đây là cách tôi nhìn thấy mọi thứ.

Ok, đây là getByIdphương thức ( getphương thức tương tự nhưng sử dụng sku thay vì id):

public function getById($productId, $editMode = false, $storeId = null, $forceReload = false)
{
    $cacheKey = $this->getCacheKey(func_get_args());
    if (!isset($this->instancesById[$productId][$cacheKey]) || $forceReload) {
        $product = $this->productFactory->create();
        if ($editMode) {
            $product->setData('_edit_mode', true);
        }
        if ($storeId !== null) {
            $product->setData('store_id', $storeId);
        }
        $product->load($productId);
        if (!$product->getId()) {
            throw new NoSuchEntityException(__('Requested product doesn\'t exist'));
        }
        $this->instancesById[$productId][$cacheKey] = $product;
        $this->instances[$product->getSku()][$cacheKey] = $product;
    }
    return $this->instancesById[$productId][$cacheKey];
}

Như bạn có thể nhận thấy mã bạn đã dán:

$productFactory->create()->load($id);

Là một phần của chức năng này.

Tuy nhiên, điều kiện bổ sung sử dụng các trường hợp được lưu trong bộ nhớ cache để tránh tải lại thêm trong trường hợp trước đây bạn đã sử dụng phương thức getByIdhoặc getphương thức cho cùng một id (hoặc sku trong trường hợp getphương thức) .

Bạn có thể nghĩ rằng một lý do chính đáng để sử dụng loadcó thể là tránh sử dụng các trường hợp được lưu trong bộ nhớ cache đó (trong trường hợp đó có thể là lý do chính đáng? Tôi không biết) nhưng getByIdcác getphương thức có một $forceReloadtham số có thể được đặt thành đúng tránh sử dụng các trường hợp bộ nhớ cache.

Đó là lý do tại sao với tôi, không có lý do chính đáng để sử dụng loadphương pháp getByIdhoặc getphương pháp.


2

Hãy hiểu sự khác biệt giữa các kho lưu trữ và bộ sưu tập.

Trong ví dụ của bạn, nếu sử dụng kho lưu trữ, bạn sẽ nhận được một mảng Magento\Catalog\Api\Data\ProductInterfacekhác với việc lấy một bộ sưu tập Magento\Catalog\Model\Product.

Các kho lưu trữ và giao diện dữ liệu cung cấp cho bạn một mức giao diện cao cần được đảm bảo là tương thích trong các phiên bản tương lai . Đây là lý do tại sao nó là phương pháp đề xuất.

Hy vọng nó giúp.

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.