เมื่อใดที่เราควรใช้ที่เก็บและโรงงานใน Magento 2


75

ฉันได้ผ่านบทช่วยสอนใน Magento 2 และสิ่งนี้ทำให้ฉันสับสนเล็กน้อย ฉันเห็นว่ามีสองวิธีที่เราสามารถอ่าน / เขียนเอนทิตีธุรกิจได้:

ดึงข้อมูล

ใช้วิธีการจากโรงงาน

$object = $this->myFactory->create();
$object->load($myId);

การใช้วิธีการเก็บข้อมูล

$repo   = $this->myRepository();
$object = $repo->getById($myId);

บันทึกข้อมูล

ใช้วิธีการจากโรงงาน

$object = $this->myFactory->create();
$object->load($myId);
$object->setData('something', 'somethingDifferent')->save();

การใช้วิธีการเก็บข้อมูล

$repo   = $this->myRepository();
$object = $repo->getById($myId);
$object->setData('something', 'somethingDifferent');
$repo->save($object);

ฉันยังสามารถเห็นว่าทั้งพื้นที่เก็บข้อมูลและชั้นโรงงานสามารถฉีดโดยใช้การฉีดพึ่งพา อย่างน้อยก็ทำให้ฉันสับสน

เมื่อใดที่เราควรใช้วิธีการจัดเก็บและวิธีการจากโรงงาน? การปฏิบัติที่ดีที่สุดที่เราต้องทำคืออะไร?


ตัวอย่างที่ดีของการใช้ Factory, CollectionFactory และ Repository สามารถดูได้ที่ \ Magento \ Setup \ Fixtures \ CategoryResolver
Ricardo Martins

คำตอบ:


72

หากมีที่เก็บและทำสิ่งที่คุณต้องการได้ดีให้เลือกที่เก็บไว้เสมอ

ที่เก็บข้อมูลเป็นส่วนหนึ่งของสัญญาบริการ (เป็นการใช้งานอินเทอร์เฟซในApi) ซึ่งหมายความว่าพวกเขามีความหมายว่าเป็นส่วนต่อประสานสาธารณะกับโมดูลอื่น ๆ

ใช้ที่เก็บสำหรับการโหลดแบบเต็ม

$model->load()ไม่ได้เป็นส่วนหนึ่งของสัญญาบริการ ฉันมีคำถามเกี่ยวกับหัวข้อนั้นคุณอาจพบคำตอบที่มีประโยชน์: เคยมีเหตุผลที่ต้องการ $ model-> load () มากกว่าสัญญาบริการหรือไม่?

ใช้โรงงานเพื่อสร้างเอนทิตีใหม่

ที่เก็บข้อมูลไม่มีวิธีในการสร้างเอนทิตีใหม่ดังนั้นในกรณีนี้คุณจะต้องใช้โรงงาน แต่ใช้โรงงานสำหรับอินเทอร์เฟซเช่นMagento\Catalog\Api\Data\ProductInterfaceFactory- มันจะสร้างการใช้งานที่ถูกต้องตามการกำหนดค่า DI

จากนั้นใช้repository->save()วิธีการบันทึก

ใช้คอลเลกชันโรงงานหากคุณต้องการการควบคุมมากขึ้น

ต่อไปนี้ไม่ใช่แนวทางปฏิบัติที่ดีที่สุดของ Magento อย่างเป็นทางการ แต่ในปัจจุบันที่เก็บข้อมูลไม่ได้ช่วยให้คุณควบคุมสิ่งที่จะโหลดได้อย่างดี API เกณฑ์การค้นหาช่วยให้คุณกำหนดตัวกรองได้ตัวอย่างเช่นไม่มีวิธีการเลือกแอททริบิว EAV เฉพาะหรือระบุตารางดัชนีที่จะเข้าร่วม

รายละเอียดการใช้งานเหล่านี้ซ่อนอยู่จาก API สัญญาบริการ แต่บ่อยครั้งที่รายละเอียดการใช้งานเหล่านี้สำคัญ ด้วยเหตุนี้ทันทีที่ที่เก็บข้อมูล จำกัด ฉันฉันไม่ลังเลที่จะใช้คอลเล็กชันพื้นฐานอีกต่อไป


2
คุณสามารถให้รหัสตัวอย่างเกี่ยวกับการใช้โรงงานเพื่อสร้างเอนทิตีใหม่ได้คำอธิบายพลาดรายละเอียดและเข้าใจยาก ขอบคุณมาก.
Key Shang


ขอบคุณ แต่use the factory for the interface, such as Magento\Catalog\Api\Data\ProductInterfaceFactory - it will create the right implementation based on DI configuration.เป็นประเด็นที่ฉันไม่สามารถเข้าใจได้คู่มือ dev ไม่แนะนำInterfaceFactoryวิธีใช้repository->save()วิธีการบันทึกเอนทิตีใหม่ ฉันสามารถใช้โรงงานเพื่อบันทึกเอนทิตีใหม่เท่านั้นไม่ใช่ที่เก็บ
Key Shang

@Key Shang หมายความว่าส่วนต่อประสานจะให้ฟังก์ชั่นชุดข้อมูลทั้งหมดให้คุณบันทึกทุกคอลัมน์ในตารางดังนั้นลองใช้ส่วนต่อประสานที่ใดก็ตามที่เป็นไปได้เพื่อบันทึกระเบียนใหม่ InterfaceFactory คลาสจะถูกสร้างขึ้นเป็นส่วนหนึ่งของ di: รวบรวมเพื่อให้คุณสามารถเห็นพวกเขาในโฟลเดอร์ var / generation
stevensagaar

@ Stevensagaar ขอบคุณฉันเข้าใจได้แล้ว
Key Shang

21

คำถามที่ดี.

แม้ว่าทั้งเก็บและโรงงานให้เราเข้าถึงกิจการผมคิดว่าเราควรจะมุ่งเน้นของพวกเขารับผิดชอบ

จากเอกสารวีโอไอพี : "โรงงานเป็นคลาสบริการที่ยกตัวอย่างคลาสที่ไม่สามารถฉีดได้นั่นคือโมเดลที่เป็นตัวแทนของเอนทิตีฐานข้อมูลพวกเขาสร้างเลเยอร์ของนามธรรมระหว่าง ObjectManager และรหัสธุรกิจ"

จากบทความของ Alan Storm : "วัตถุเก็บข้อมูลมีหน้าที่รับผิดชอบในการอ่านและเขียนข้อมูลวัตถุของคุณไปยังที่เก็บวัตถุ"

การตีความของฉันคือ: หากวัตถุประสงค์ของเราคือการทำงานกับวัตถุที่ไม่สามารถฉีดได้ (เรียกว่า "newable") เราควรใช้โรงงาน ถ้าเรามุ่งเน้นไปที่การค้นหา / การอ่าน / การเขียนวัตถุภายในที่เก็บวัตถุเราควรใช้ที่เก็บ

นี่คือวิธีการในอุดมคติของฉันในหัวข้อ; โปรดทราบว่าการใช้งานจริงอาจบังคับให้เราทำสิ่งต่าง ๆ ตามที่อลันระบุไว้

สนุก.


5

ฉันจะบอกว่ามันเป็นการเริ่มต้นที่จะใช้คลังเก็บข้อมูลเพราะพวกเขาอนุญาตให้แยกรหัสระหว่างการอ่าน / เขียนข้อมูลและตรรกะทางธุรกิจ

มีบทความที่มีรายละเอียดมากเขียนโดย Alan Storm เกี่ยวกับเรื่องนี้อธิบายวิธีใช้ที่เก็บ แต่ยังมองถึงข้อเสียบางประการของวิธีการใหม่นี้: http://alanstorm.com/magento_2_understanding_object_repositories/

นอกจากนี้จากเอกสาร Magento อธิบายถึงประโยชน์ของ aproach ใหม่นี้: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/service-contracts/service-contracts.html


2
ขอบคุณสำหรับคำตอบ. ที่จริงฉันได้รับข้อสงสัยนี้บนหัวของฉันจากบทความของ alanstorm ถ้าตัวเอง :)
Rajeev K Tomy

3
แน่นอนมันทำให้คุณคิด แต่นั่นอาจเป็นสิ่งที่ดี แม้ว่านี่จะเป็นแนวปฏิบัติที่ดีที่สุดที่ Magento แนะนำ แต่ก็ไม่ได้หมายความว่านักพัฒนาซอฟต์แวร์ไม่สามารถตั้งคำถามและวิจารณ์บางแง่มุมของมันได้ นอกจากนี้ยังมีสถานการณ์ที่ไม่ครอบคลุมโดยที่เก็บ อย่างไรก็ตามในบริบทของการสร้างส่วนขยายที่จะไม่ทำลายการเผยแพร่ในอนาคตโดยใช้ที่เก็บควรได้รับการพิจารณา นอกจากนี้ฉันแน่ใจว่าพวกเขาจะพัฒนาต่อไปและให้ความคุ้มครองเพิ่มเติมเกี่ยวกับสิ่งที่นักพัฒนาต้องการ
Marina Vilcea

ฉันเห็นด้วยกับความคิดเห็นของคุณ 100% ฉันหวังอย่างนั้นจริงๆ โปรดดูคำตอบของ fabian ด้วยเช่นกัน
Rajeev K Tomy

ใช่ฉันเห็น :) ตอบโต้คำตอบของเขาแล้ว ขอบคุณสำหรับคำถามที่ยอดเยี่ยม!
Marina Vilcea

นอกจากนี้ฉันอ่านที่ไหนสักแห่งที่ใช้วิธีการจัดการข้อมูลระดับต่ำกว่าก็โอเคในสคริปต์การติดตั้ง / อัปเกรด$setup->updateTableRow(...);หรือโรงงานฉันไม่แน่ใจ แต่รู้สึกว่าข้อโต้แย้งสำหรับการใช้ระดับที่สูงกว่านำไปใช้กับพื้นที่นั้นเช่นกันคุณคิดอย่างไร
medmek

1

หวังว่าคำตอบนี้อาจช่วยนักพัฒนาส่วนขยายอื่น ๆ ได้เช่นกัน

เราต้องบันทึกโมเดลโดยใช้ Repository เท่านั้น

  1. โมเดลโรงงานใน Magento 2 เก็บข้อมูลที่ จำกัด ไว้มาก
  2. ในทางกลับกันแบบจำลองพื้นที่เก็บข้อมูลมีข้อมูลทั้งหมดในกรณีของแอตทริบิวต์ eav ที่เกี่ยวข้องกับลูกค้าผลิตภัณฑ์ ฯลฯ
  3. สำหรับรูปแบบการบันทึกให้ใช้ที่เก็บข้อมูลเพื่อบันทึกเอนทิตีเสมอหากใช้แบบจำลองโรงงานสำหรับการบันทึกแบบจำลองจะลบแอททริบิวต์ eav ที่ไม่ใช่ระบบทั้งหมดที่เกี่ยวข้องกับเอนทิตีนั้น (ลูกค้าผลิตภัณฑ์ ฯลฯ )

  4. สำหรับวัตถุประสงค์ในการโหลดโมเดล Repository เป็นตัวเลือกที่ดีที่สุดในการรับโมเดลโดยใช้เมธอด getById ()

ฉันจะแนะนำให้ใช้ Repository มากที่สุดโดยเฉพาะเพื่อวัตถุประสงค์ในการบันทึกแบบจำลอง


1

ตอนนี้โหลด, บันทึก, ลบเมธอด (โมเดล) ถูกคัดค้านดังนั้นเราจึงสามารถใช้โมเดลทรัพยากรหรือที่เก็บ

Magento ตอนนี้ใช้แนวคิดผู้จัดการเอนทิตีสำหรับการบันทึกการลบการโหลด

ตัวแบบทรัพยากรมีวัตถุตัวจัดการเอนทิตีเพื่อทำตามการดำเนินการเหล่านั้น

$categoryModel = $this->_objectManager->create('\Magento\Catalog\Model\CategoryFactory')->create();        
  $categoryResource = $this->_objectManager->create('\Magento\Catalog\Model\ResourceModel\Category');        
  $categoryResource->load($categoryModel, 3);        
  echo $categoryModel->getName();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.