มีเหตุผลใดที่จะชอบ $ 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'sget / getByIdแทนที่จะเป็นload()วิธีการของ ProductFatory เป็นเพราะอดีตมีระดับสูงกว่าหลัง

ตอบProductRepository- เช่นเดียวกับProductFactory- อาจส่งคืนProduct โมเดลแต่นั่นไม่ใช่สิ่งที่ M2 ต้องการให้คุณพิจารณา นั่นไม่ใช่สิ่งที่\Magento\Catalog\Api\ProductRepositoryInterface::getById()บล็อก doc พูด มันบอกว่า@return \Magento\Catalog\Api\Data\ProductInterfaceซึ่งเป็นอินเตอร์เฟซผลิตภัณฑ์รูปแบบคือการใช้

ดังนั้นคุณควรใช้เลเยอร์ API ทุกครั้งที่ทำได้เพราะ:

  • Api/Data layer ถูกใช้ใน Web Api เช่นกัน
  • แบบจำลองสามารถ - และอาจจะ - ถูก refactored ในบางจุด; Api/Data/Productจะไม่
  • ในการรับผลิตภัณฑ์ในชั้นเรียนของคุณคุณจะต้องฉีดโรงงานคอนกรีต ( ProductFactory) หรืออินเทอร์เฟซ ( ProductRepository) ฉันไม่คิดว่าคุณต้องการให้โมดูลของคุณพึ่งพาสิ่งใดนอกจากอินเทอร์เฟซ ดังนั้นฉันไม่เห็นด้วยกับการฉีดประเภทนี้

ฉันคิดว่ามันเป็นเพียงเลเยอร์ abstraction เล็ก ๆ อีกอันหนึ่งเหนือโมเดลเพื่อรองรับ Web API (REST, SOAP และอื่น ๆ )

การอ้างคำตอบนี้ :

หวังว่าคุณจะรักสัญญาการบริการเมื่อโมดูลที่กำหนดเองของคุณจะไม่แตกหลังจาก Magento 2 รุ่นถัดไป (แน่นอนถ้าคุณไม่ข้ามสัญญาบริการและใช้โมเดล / คอลเลกชัน / โมเดลทรัพยากรโดยตรง) และเมื่อคุณเริ่มบริโภค / เปิดเผย Magento 2 web API ซึ่งตอนนี้เป็นไปตามสัญญาบริการเดียวกัน ดังนั้นคุณต้องทำการเปลี่ยนแปลงเพียงแห่งเดียว (เช่นผ่านปลั๊กอิน) และพวกเขาจะถูกนำไปใช้ทุกที่ นี่เป็นไปไม่ได้ใน Magento 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วิธีการgetById/ getวิธี

ฉันไม่ได้บอกว่าฉันพูดถูก แต่นี่คือสิ่งที่ฉันเห็น

ตกลงดังนั้นนี่เป็นgetByIdวิธีการ ( getวิธีการจะคล้ายกัน แต่ใช้ sku แทน 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];
}

ในขณะที่คุณสามารถสังเกตเห็นรหัสที่คุณวาง:

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

เป็นส่วนหนึ่งของฟังก์ชั่นนี้

อย่างไรก็ตามเงื่อนไขพิเศษใช้อินสแตนซ์แคชเพื่อหลีกเลี่ยงการโหลดซ้ำในกรณีที่คุณเคยใช้getByIdหรือgetวิธีการสำหรับรหัสเดียวกัน (หรือ sku ในกรณีของgetวิธีการ)วิธีการ)

คุณอาจคิดว่าเหตุผลที่ดีในการใช้loadอาจหลีกเลี่ยงการใช้อินสแตนซ์แคชเหล่านั้น (ซึ่งในกรณีนี้อาจเป็นเหตุผลที่ดีที่ฉันไม่รู้) แต่วิธีgetByIdการและgetมี$forceReloadพารามิเตอร์ที่สามารถตั้งค่าเป็นจริงถึง หลีกเลี่ยงการใช้แคชอินสแตนซ์เหล่านั้น

นั่นเป็นเหตุผลที่ฉันไม่มีเหตุผลที่ดีที่จะใช้loadวิธีการgetByIdหรือgetวิธีการมากกว่า


2

โปรดเข้าใจความแตกต่างระหว่างที่เก็บและคอลเลกชัน

ในตัวอย่างของคุณหากใช้ที่เก็บคุณจะได้รับอาร์เรย์ Magento\Catalog\Api\Data\ProductInterfaceที่แตกต่างจากการเก็บรวบรวมMagento\Catalog\Model\Productที่แตกต่างจากการได้รับคอลเลกชันของ

ที่เก็บข้อมูลและส่วนต่อประสานข้อมูลช่วยให้คุณมีระดับส่วนต่อประสานที่สูงซึ่งควรจะรับประกันได้ว่าสามารถใช้งานร่วมกันได้ในอนาคตrelases นี่คือสาเหตุที่เป็นแนวทางที่แนะนำ

หวังว่ามันจะช่วย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.