Magento 2 Helper เช่น


11

เมื่อฉันคิดว่าฉันเอาหัวของฉันพันรอบระบบ DI จาก Magento 2 มีบางอย่างเกิดขึ้นและไม่ห่อหุ้ม
ฉันเห็นรหัสหลักในวิธีต่างๆในการเข้าถึงตัวช่วย
ตัวอย่างเช่นในMagento\Catalog\Controller\Category::_initCategoryสิ่งนี้:

if (!$this->_objectManager->get('Magento\Catalog\Helper\Category')->canShow($category)) {
    return false;
}

แต่ในMagento\Catalog\Block\Category\Viewตัวช่วยถูกฉีดเข้าไปในตัวสร้างเขา

public function __construct(
    \Magento\Framework\View\Element\Template\Context $context,
    \Magento\Catalog\Model\Layer\Category $catalogLayer,
    \Magento\Framework\Registry $registry,
    \Magento\Catalog\Helper\Category $categoryHelper,
    array $data = array()
) {
    $this->_categoryHelper = $categoryHelper;
    $this->_catalogLayer = $catalogLayer;
    $this->_coreRegistry = $registry;
    parent::__construct($context, $data);
}

นี้ทำให้ฉันคิดว่าผู้ช่วยเหลือควรจะแตกต่างกันในการเข้าถึงตัวควบคุมและบล็อก (และรุ่น) Magento\Catalog\Controller\Adminhtml\Product\Action\Attributeแต่แล้วผมพบว่าตัวควบคุมที่เป็นผู้ช่วยที่ถูกฉีดในตัวสร้างที่

โปรดล้างหมอกให้ฉันด้วย
ฉันควรใช้ DI และควรใช้เมื่อobjectManagerใด และทำไม?
ฉันได้อ่านคำถามนี้: อินสแตนซ์ช่วยในวีโอไอพี 2 นี่เป็นเพียงคำถามติดตามที่

คำตอบ:


10

ฉันชอบ DI มากที่สุดเท่าที่เป็นไปได้เนื่องจากการใช้ตัวจัดการวัตถุนั้นเป็นการฝ่าฝืนกฎหมายว่าด้วยความผิดทางอาญา เมื่อใช้ตัวจัดการวัตถุการพึ่งพาเหล่านี้จะถูกซ่อนอยู่ในตรรกะวิธี


อ๋อ ฉันเห็นด้วย. ฉันจะใช้ DI แต่ฉันอยากรู้ว่าทำไมสิ่งนี้ถึงเกิดขึ้นในแกนกลาง อาจมีบางคนที่ไม่ได้ไปปรับโครงสร้างชั้นเรียนที่ฉันกล่าวถึงอีกครั้ง?
Marius

Afaik พวกเขายังคงฟื้นฟูสภาพเป็นอย่างมากและหวังว่าพวกเขาจะสัมผัสสถานที่เหล่านี้เช่นกัน แต่ยังไม่ทราบเกี่ยวกับลำดับความสำคัญซึ่งจะต้องมีอยู่หากพวกเขาต้องการปล่อยจริงในบางจุด ดังนั้นอาจมีฟีเจอร์ใหม่หรือการปฏิบัติที่ไม่ดีอื่น ๆ จะได้รับการแก้ไขก่อน
โทเบียส

จะเกิดอะไรขึ้นถ้าคุณมีคลาสของฟังก์ชันที่ 10 และเพียง 1 ฟังก์ชันที่ต้องใช้รูปแบบเฉพาะ จะไม่ซ้ำซ้อน (จากมุมมองประสิทธิภาพการทำงาน) เพื่อโหลดโมเดลผ่านการสร้างคอนสตรัคชันสำหรับฟังก์ชั่นทั้ง 10 ฟังก์ชั่นในขณะที่เราสามารถโหลดมันได้โดยใช้ตัวจัดการวัตถุภายใน 1 ฟังก์ชันเดียว
JohnyFree

6

ผมไม่ทราบว่ามากเกี่ยวกับการดำเนินงานวีโอไอพี แต่ดูเหมือนว่าObjectManagerเป็นสบริการ

โดยทั่วไปใช้บริการสอ้างอิงในการเข้าถึงวัตถุที่ไม่ดีงาม, เช็คเอาท์ออกจากบทความนี้

การกำหนดการพึ่งพาของคุณอย่างชัดเจนผ่านคอนสตรัคเตอร์เป็นวิธีการที่ดีกว่ามาก มันช่วยในการทดสอบหน่วยและปัญหาเวลาทำงานกับบริการที่ไม่ได้กำหนดไว้

การฉีด Object Manager เข้าไปในชั้นเรียนนั้นเป็นการฉีด Registry ในชั้นเรียนของคุณซึ่งมีการเข้าถึงบริการแอปพลิเคชันทั้งหมดของคุณซึ่งเห็นได้ชัดว่าไม่ถูกต้อง

ฉันใช้ZF2เป็นธรรมและโดยทั่วไปจะกำหนดคลาสโรงงานขนาดเล็กสำหรับบริการตัวควบคุมและคลาสใด ๆ ที่ต้องการการพึ่งพา คลาสโรงงานเหล่านี้มีการเข้าถึงตัวระบุบริการและคว้าบริการทั้งหมดที่วัตถุขึ้นอยู่กับและแทรกมันผ่านตัวสร้าง การใช้บริการสในระดับโรงงานจะปรับมันเป็นส่วนใหญ่ทิ้งรหัสบางอย่างเช่นนี้ตัวอย่างเช่น

โรงงานเหล่านี้ยังคงทดสอบได้ง่าย

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

นี่คือจากคนที่มีการสัมผัสกับ patters ดังกล่าวข้างต้น จำกัด ดังนั้นฉันอยากจะได้ยินความคิด / ประสบการณ์ของผู้อื่นในเรื่อง!

อ่านเพิ่มเติม


ขอบคุณสำหรับคำอธิบายที่ดี คำถามของฉันคือ "ทำไมมี 2 วิธีในการเข้าถึงผู้ช่วยในแกนกลาง" ดังนั้นนี่เป็นบิตนอกหัวข้อ แต่มันเคลียร์ข้อสงสัยอื่น ๆ ที่ฉันมี :) ขอบคุณ
Marius

ฉันอาจจะบอกว่ามันเป็นเพียงสิ่งที่ยังไม่ได้รับการฟื้นฟู อาจเป็นสิ่งที่ง่ายต่อการใช้งาน ผู้บริโภคที่ต้องการให้ฉีดการพึ่งพาทั้งหมดของพวกเขาในคอนโทรลเลอร์เป็นประจำจะเห็นว่าเป็นการต่อต้านโดยเฉพาะอย่างยิ่งเมื่อทำการ RAD การให้ผู้บริโภคทั้งสองวิธีในการเข้าถึงการพึ่งพานั้นจะอนุญาตให้ใช้วิธีการ RAD แต่ก็ยังอนุญาตให้ผู้อื่นกำหนดการพึ่งพาของพวกเขาอย่างชัดเจนหากพวกเขาต้องการ
Aydin Hassan

5

อีกวิธีหนึ่งในการใช้ตัวช่วย (ในเทมเพลต) คือ:

$this->helper('[Vendor]\[Module]\Helper\[Helper Name]')->getMethodName();

ฉันหวังว่ามันจะมีประโยชน์ถ้าคุณยังไม่รู้


สิ่งนี้คล้ายกับการใช้ตัวจัดการวัตถุ ไม่แน่ใจว่าเป็นความคิดที่ดีที่สุด
Marius

1
วิธีดังกล่าวเป็นเพียงสำหรับเทมเพลตเท่าที่ฉันรู้ ผู้จัดการวัตถุถูกนำมาใช้ในตัวควบคุมบล็อกรูปแบบอื่น ๆ
rbncha

1
มันไม่ได้อยู่ใน ballpark เดียวกับรหัสเพราะไม่มีการพึ่งพารหัสในแม่แบบ เทมเพลตเป็นเพียงผู้บริโภคและไม่ทำให้ลูกค้าเสียด้วยการห่อหุ้มที่ไม่สมบูรณ์
demonkoryu

ฉันไม่รู้ว่าปีศาจkoryuกำลังพยายามจะพูดอะไร แต่วิธีที่ดีที่สุดในการเรียกผู้ช่วยของโมดูลก็คือ นี่คือวีโอไอพี ดังที่พวกเขากล่าวว่ารหัสบล็อก / ส่วนทุกคนมีจุดประสงค์ที่จะเรียก / แก้ไขได้โดยไม่ต้องสัมผัสแกน ดังนั้นทุกอย่างเกี่ยวข้องกันหรือมีการพึ่งพา
rbncha

2

แม้ว่าจะเป็นคำถามเก่า แต่ฉันไม่แน่ใจว่าMariusจะได้รับคำตอบหรือไม่ ฉันเชื่อว่าMariusสามารถตอบได้ดีกว่า ฉันต้องการตอบสั้น ๆ ทำไม Magento 2 แนะนำให้ใช้ DI แทนที่จะเป็นตัวช่วย?

  • ทำให้การแยกในการทดสอบหน่วยเป็นไปได้ / ง่าย
  • การกำหนดการขึ้นต่อกันของคลาสอย่างชัดเจน
  • ยกตัวอย่างเช่นการออกแบบที่ดี (หลักการความรับผิดชอบเดี่ยว (SRP))
  • การใช้ DI ในโมดูลของคุณจะช่วยลดความเสี่ยงของข้อบกพร่องที่เข้ากันไม่ได้เมื่อ Magento เปลี่ยนการใช้อินเตอร์เฟซเหล่านั้น นี่เป็นแนวคิดสำคัญที่จะเข้าใจสำหรับนักพัฒนาส่วนขยาย

ทำไม M2 core อาจไม่ใช้ DI ในบางกรณี?

  • ลดจำนวนคลาส
  • ไม่ได้สร้างอินเทอร์เฟซที่ไม่จำเป็น
  • ไม่มีความเสี่ยงจากข้อบกพร่องที่เข้ากันไม่ได้

แม้ว่าโมดูลแคตตาล็อกหลักได้รับการใช้ตัวช่วย แต่ก็ใช้ DI อย่างกว้างขวาง จากการวิจัยของฉันฉันพบว่า Magento 2 ใช้ฟังก์ชั่นบางอย่างในไฟล์ตัวช่วยหลักของแคตตาล็อกซึ่งไม่เหมาะสำหรับสัญญาบริการ

หากคุณต้องใช้คลาสที่กำหนดโดยวีโอไอพีอย่างชัดเจน (เช่น \ Magento \ Catalog \ Model \ Product) ให้ทำการอ้างอิงโดยนัยอย่างชัดเจนโดยขึ้นอยู่กับการใช้งานที่เป็นรูปธรรมแทนที่จะใช้อินเทอร์เฟซสัญญาบริการ

นักพัฒนาส่วนขยายควรใช้ DI แทน Magento1 อย่าง Helper เมื่อดำเนินการตามแนวทางของ Magento 2 fallout นั้นมี จำกัด เมื่อทำลายคำแนะนำปัญหาจะเกิดขึ้น


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