サービス契約よりも$ 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

ProductFatoryのメソッドの代わりにProductRepositorys get/ を使用する理由は、前者が後者よりも高いレベルにあるためです。getByIdload()

A- ProductRepositoryちょうどProductFactorya-はProduct モデルを返すかもしれませんが、それはM2があなたに考慮して欲しいことではありません。それはdocブロックの言うことではありません\Magento\Catalog\Api\ProductRepositoryInterface::getById()。これは@return \Magento\Catalog\Api\Data\ProductInterface、Product モデルが実装しているインターフェースです。

そのため、可能な場合はいつでもAPIレイヤーを使用する必要があります。理由は次のとおりです。

  • Api/Data レイヤーはWeb Apiでも使用されます
  • モデルはある時点でリファクタリングできます-おそらくそうなります- Api/Data/Productしない。
  • クラスで製品を取得するには、具体的なファクトリ(ProductFactory)またはインターフェイス(ProductRepository)を挿入する必要があります。モジュールがインターフェイス以外のものに依存することは望ましくないと思います。それで、私はこのタイプの注射に反対します。

Web API(REST、SOAPなど)に対応するために、モデルの上の別の小さな抽象化レイヤーに過ぎないと考えています。

この答えを引用:

Magento 2の次のリリース後にカスタムモジュールが破損しない場合は、サービスコントラクトが気に入っていただければ幸いです(もちろん、サービスコントラクトをバイパスせず、モデル/コレクション/リソースモデルを直接使用しない場合)。また、Magento 2 Web APIの使用/公開を開始すると、現在は同じサービス契約に基づいています。そのため、変更は1か所(プラグインなど)でのみ行う必要があり、それらはどこにでも適用されます。これはMagento 1では不可能でした。


正確に私が求めていたものではありませんが、それは私が考えたことでもあります、確認ありがとう!
ファビアンシュメングラー16

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

はい、それは理にかなっています:)
ファビアンシュメングラー

14

私にはloadgetById/ getメソッドよりもメソッドを使用する理由はありません。

私は正しいとは言いませんが、ここに私が物事を見る方法があります。

わかりましたので、ここにメソッドがありますgetByIdgetメソッドは似ていますが、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メソッドオーバーgetByIdgetメソッドを使用する正当な理由はありません。


2

リポジトリとコレクションの違いを理解してください。

あなたの例では、リポジトリを使用する場合Magento\Catalog\Api\Data\ProductInterface、のコレクションを取得するのとは異なる配列を取得します Magento\Catalog\Model\Product

リポジトリとデータインターフェイスは、将来のリリースで互換性があると保証される高いインターフェイスレベルを提供します。これが提案されたアプローチである理由です。

それが役に立てば幸い。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.