क्या सेवा अनुबंध पर $ मॉडल-> लोड () को प्राथमिकता देने का कोई कारण है?


24

मैं समझता हूं कि Magento 2 में मॉड्यूल के बीच काम करने का पसंदीदा तरीका सेवा अनुबंध का उपयोग कर रहा है।

इसलिए यदि मैं किसी उत्पाद को लोड करना चाहता हूं, तो मैं उत्पाद भंडार का उपयोग करता हूं:

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

जो अनुबंध के एक उदाहरण से लौट रहा है Magento\Catalog\Api\Data\ProductInterface

लेकिन मैं इसके बजाय पुराने तरीके का उपयोग कर सकता हूं, डोमेन लेयर को सीधे कॉल कर रहा हूं:

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

क्या कोई ऐसा मामला है जहां यह आवश्यक या उपयोगी होगा?

देवदूत कहते हैं (प्रकाश डाला गया):

एक मॉड्यूल दूसरे मॉड्यूल में सीधे कॉल कर सकता है। यह कसकर युग्मित समाधान ज्यादातर स्थितियों के लिए अनुशंसित नहीं है, लेकिन कभी-कभी अपरिहार्य है

[...]

किसी अन्य मॉड्यूल के डोमेन-लेयर कोड को कॉल करने की आपकी रणनीति आपके सिस्टम के अनूठे कॉन्फ़िगरेशन और जरूरतों पर अत्यधिक निर्भर है।

स्रोत: http://devdocs.magento.com/guides/v2.0/altecture/archi_perspectives/domain_layer.html

और संबंधित प्रश्न पर एक टिप्पणी में कहा गया है:

रिपोजिटरी का उपयोग करने से आपको एक उत्पाद डेटा मॉडल ( Api/Data/Product) मिलेगा , जो एक उत्पाद मॉडल को डंबड-डाउन डीटीओ में परिवर्तित किया जाता है। कुछ विचार करने के लिए, क्योंकि वे काफी अलग हैं

लेकिन जहां तक ​​मैं देख सकता हूं कि वस्तुएं सामान्य परिस्थितियों में समान हैं, बस प्रति phpDoc के प्रकार भिन्न हैं ( Magento\Catalog\Api\Data\ProductInterface/ Magento\Catalog\Model\Product)

जवाबों:


23

ProductFatory की विधि के बजाय / ProductRepositorys का उपयोग करने का कारण यह है कि पूर्व उत्तरार्द्ध की तुलना में उच्च स्तर का है।getgetByIdload()

ProductRepository- जैसे एक ProductFactory- एक Product मॉडल वापस कर सकता है , लेकिन वह नहीं है जो एम 2 आपको विचार करना चाहता है। ऐसा इसलिए है नहीं क्या \Magento\Catalog\Api\ProductRepositoryInterface::getById()के दस्तावेज़ ब्लॉक कहते हैं। यह कहता है @return \Magento\Catalog\Api\Data\ProductInterface, जो एक इंटरफ़ेस है जिसे एक उत्पाद मॉडल लागू कर रहा है।

इसलिए, जब भी संभव हो, आपको एपीआई लेयर का उपयोग करना चाहिए, क्योंकि:

  • Api/Data लेयर का उपयोग वेब एपी में भी किया जाता है
  • मॉडल कर सकते हैं - और शायद - किसी बिंदु पर फिर से बनाए जाएंगे; Api/Data/Productनहीं होगा।
  • अपनी कक्षाओं में एक उत्पाद प्राप्त करने के लिए, आपको या तो एक ठोस कारखाने ( ProductFactory) या एक इंटरफ़ेस ( ProductRepository) को इंजेक्ट करने की आवश्यकता है । मुझे नहीं लगता कि आप चाहते हैं कि आपका मॉड्यूल किसी चीज़ पर निर्भर हो, लेकिन एक इंटरफ़ेस। इसलिए मैं इस प्रकार के इंजेक्शन से असहमत हूं ।

मैं इसे वेब API (REST, SOAP आदि) के लिए पूरा करने के लिए मॉडल के ऊपर एक और छोटी अमूर्त परत मानता हूं ।

इस उत्तर को उद्धृत करते हुए :

उम्मीद है, आपको सेवा अनुबंध पसंद आएगा जब मैगेंटो 2 की अगली रिलीज़ के बाद आपका कस्टम मॉड्यूल नहीं टूटेगा (यदि आप सेवा अनुबंध को बायपास नहीं करते हैं और सीधे मॉडल / संग्रह / संसाधन मॉडल का उपयोग करते हैं)। और जब आप Magento 2 वेब API का उपभोग / खुलासा करना शुरू करते हैं, जो अब उसी सेवा अनुबंध पर आधारित है। इसलिए आपको केवल एक ही स्थान पर परिवर्तन करना होगा (जैसे प्लगइन के माध्यम से) और उन्हें हर जगह लागू किया जाएगा। यह Magento 1 में असंभव था।


बिल्कुल नहीं मैं क्या पूछ रहा था, लेकिन मैंने जो सोचा था, पुष्टि के लिए धन्यवाद!
फेबियन शेंगलर

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एक की। क्या यह बेहतर है? :)
नेवरमाइंड

हां, इससे समझ में आता है :)
फेबियन शेंगलर

14

मेरे लिए, loadविधि getById/ getविधि से अधिक उपयोग करने का कोई कारण नहीं है ।

मैं यह नहीं कहता कि मैं सही हूं, लेकिन यहां मैं चीजों को देखता हूं।

ठीक है तो यहाँ getByIdविधि ( getविधि समान है लेकिन आईडी के बजाय स्क्यू का उपयोग करता है):

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उसी आईडी के लिए विधि का उपयोग कर सकें (या getविधि के मामले में sku ) से बचने के लिए

आप सोच सकते हैं कि उपयोग करने का एक अच्छा कारण loadउन कैश्ड उदाहरणों का उपयोग करने से बचना हो सकता है (जिस स्थिति में यह एक अच्छा कारण हो सकता है? मुझे नहीं पता) लेकिन getByIdऔर getविधियों में एक $forceReloadपैरामीटर है जिसे सही करने के लिए सेट किया जा सकता है। उन कैश इंस्टेंस का उपयोग करने से बचें।

इसीलिए मेरे पास, loadविधि getByIdया getविधियों का उपयोग करने का कोई अच्छा कारण नहीं है ।


2

कृपया रिपॉजिटरी और संग्रह के बीच अंतर को समझें।

आपके उदाहरण में, यदि रिपॉजिटरी का उपयोग करते हैं, तो आपको एक सरणी मिलेगी जिसका Magento\Catalog\Api\Data\ProductInterfaceसंग्रह प्राप्त करने से अलग है Magento\Catalog\Model\Product

रिपॉजिटरी और डेटा इंटरफ़ेस आपको एक उच्च इंटरफ़ेस स्तर प्रदान करता है जिसे भविष्य के रिलेसेस में संगत के रूप में गारंटी दी जानी चाहिए । यही कारण है कि यह सुझाया गया दृष्टिकोण है।

आशा करता हूँ की ये काम करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.