서비스 계약보다 $ model-> load ()를 선호하는 이유가 있습니까?


24

Magento 2에서 모듈 간 작업을 선호하는 방법은 서비스 계약을 사용하는 것입니다.

따라서 제품을로드하려면 제품 리포지토리를 사용합니다.

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

계약을 통해 인스턴스를 반환합니다 Magento\Catalog\Api\Data\ProductInterface.

그러나 대신 도메인 계층을 직접 호출하여 이전 방식을 사용할 수도 있습니다.

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

이것이 필요하거나 유용한 경우가 있습니까?

devdocs는 말합니다 (강조 표시됨).

모듈은 다른 모듈을 직접 호출 할 수 있습니다. 이 밀접하게 결합 된 솔루션은 대부분의 상황에 권장되지 않지만 때로는 피할 수없는 경우도 있습니다.

[...]

다른 모듈의 도메인 계층 코드를 호출하는 전략은 시스템의 고유 한 구성 및 요구에 크게 의존합니다.

출처 : http://devdocs.magento.com/guides/v2.0/architecture/archi_perspectives/domain_layer.html

관련 질문에 대한 의견 은 다음과 같습니다.

리포지토리를 사용하면 제품 데이터 모델 ( Api/Data/Product)이 제공됩니다.이 모델은 멍청한 DTO로 변환 된 제품 모델입니다. 그것들이 상당히 다르기 때문에 고려해야 할 것

그러나 내가 알 수있는 한 객체는 정상적인 조건에서 동일하지만 phpDoc 당 반환 유형 만 다릅니다 ( Magento\Catalog\Api\Data\ProductInterface/ Magento\Catalog\Model\Product)

답변:


23

사용하는 이유 ProductRepository'들 get/ getById대신 ProductFatory의의 load()방법 전자가 후자보다 더 높은 수준의이기 때문이다.

A ProductRepository와 마찬가지로 A ProductFactoryProduct 모델을 반환 할 수 있지만 M2에서 고려 하지 않은 것은 아닙니다 . 그것은 doc 블록이 말하는 것이 아닙니다\Magento\Catalog\Api\ProductRepositoryInterface::getById() . @return \Magento\Catalog\Api\Data\ProductInterface제품 모델 이 구현 하는 인터페이스 인 이라고 말합니다 .

따라서 가능한 경우 API 계층을 사용해야합니다.

  • Api/Data 레이어는 웹 API에서도 사용됩니다.
  • 모델은 어느 시점에서 리팩토링 될 수 있으며 아마도 리팩토링 될 것이다. Api/Data/Product하지 않을 것이다.
  • 수업 중에 제품을 얻으려면 콘크리트 팩토리 ( ProductFactory) 또는 인터페이스 ( ProductRepository) 를 주입해야합니다 . 모듈이 인터페이스 이외의 것에 의존하기를 원하지 않는다고 생각합니다. 따라서 나는 이런 유형의 주사에 동의하지 않습니다 .

웹 API (REST, SOAP 등)를 제공하기 위해 모델 위의 또 다른 작은 추상화 계층이라고 생각합니다 .

답변을 인용 :

Magento 2의 다음 릴리스 이후에 커스텀 모듈이 깨지지 않을 때 서비스 계약을 좋아하길 바랍니다 (물론 서비스 계약을 우회하지 않고 모델 / 컬렉션 / 리소스 모델을 직접 사용하는 경우). 그리고 이제 동일한 서비스 계약을 기반으로하는 Magento 2 웹 API를 사용 / 노출하기 시작할 때. 따라서 한 곳에서만 (예 : 플러그인을 통해) 변경해야하며 모든 위치에 적용됩니다. 마 젠토 1에서는 불가능했습니다.


정확히 내가 요구 한 것이 아니라 그 점 또한 제가 생각한 것입니다. 확인 감사합니다!
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?. 예 : 당신이 전화를해야 할 때 모델 의 방법이 아닌 Api/Data/Product의 하나. 이게 더 낫습니까? :)
nevvermind

그렇습니다, 그것은 말이됩니다 :)
Fabian Schmengler

14

나에게 / 메소드 load보다 메소드 를 사용할 이유가 없습니다 .getByIdget

나는 내가 옳다고 말하지는 않지만 여기에 내가 사물을 보는 방법이 있습니다.

자, 여기 메소드가 있습니다 getById( get메소드는 비슷하지만 id 대신 sku를 사용합니다).

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];
}

붙여 넣은 코드를 볼 수 있듯이

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

이 기능의 일부입니다.

그러나 추가 조건 은 캐시 된 인스턴스를 사용하여 이전 에 동일한 ID에 대해 getById또는 get메소드를 사용한 경우 (또는 get메소드의 경우 sku) 추가 재로드를 피합니다 .

당신은 사용에 좋은 이유라고 생각 할 수있다 load(이 경우 그게 내가 모르는? 좋은 이유가 될 수있다) 캐시 된 인스턴스를 사용하지 않는 것이있을 수 있지만 getByIdget방법은이 $forceReloadtrue로 설정 될 수 매개 변수를 해당 캐시 인스턴스를 사용하지 마십시오.

그래서 나에게 load방법 오버 getById또는 get메소드 를 사용해야 할 이유가 없습니다 .


2

리포지토리와 컬렉션의 차이점을 이해하십시오.

예를 들어, 리포지토리를 사용 Magento\Catalog\Api\Data\ProductInterface하는 경우 컬렉션을 얻는 것과 다른 배열을 얻게됩니다 Magento\Catalog\Model\Product.

리포지토리와 데이터 인터페이스 는 향후 관계에서 호환 될 수 있도록 높은 수준의 인터페이스를 제공합니다 . 이것이 제안 된 접근법 인 이유입니다.

도움이 되길 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.