ตกลงดังนั้นเมื่อวานนี้เราได้มีการพูดคุยใหญ่กับคนอื่น ๆ จากชุมชนวีโอไอพีเกี่ยวกับการใช้งานโดยตรงของObjectManager
ในชั้นเรียน / แม่แบบ
ฉันได้ทราบถึงสาเหตุที่เราไม่ควรใช้ ObjectManager โดยตรงโดยอ้างถึง Alan Kent :
มีสาเหตุหลายประการ รหัสจะใช้งานได้ แต่เป็นแนวปฏิบัติที่ดีที่สุดที่จะไม่อ้างอิงคลาส ObjectManager โดยตรง
- เพราะเราพูดอย่างนั้น! ;-) (แสดงได้ดีกว่าเนื่องจากรหัสที่สอดคล้องกันคือรหัสที่ดี)
- รหัสสามารถใช้กับกรอบการฉีดที่แตกต่างกันในอนาคต
- การทดสอบนั้นง่ายกว่า - คุณผ่านการจำลองแบบอาร์กิวเมนต์สำหรับคลาสที่ต้องการโดยไม่ต้องให้ ObjectManager จำลอง
- มันช่วยให้การพึ่งพาชัดเจนยิ่งขึ้น - เป็นที่ชัดเจนว่ารหัสขึ้นอยู่กับผ่านรายการคอนสตรัคแทนที่จะมีการพึ่งพาที่ซ่อนอยู่ในช่วงกลางของรหัส
- มันสนับสนุนให้โปรแกรมเมอร์คิดเกี่ยวกับแนวความคิดเช่นการห่อหุ้มและการทำให้เป็นโมดูลได้ดีขึ้น - ถ้าคอนสตรัคเตอร์มีขนาดใหญ่บางทีมันอาจเป็นสัญญาณที่รหัสจำเป็นต้องทำการเปลี่ยนใหม่
จากสิ่งที่ฉันเห็นใน StackExchange ผู้คนจำนวนมากมักจะไปหาวิธีแก้ปัญหาที่ง่าย / สั้น / ไม่แนะนำเช่นบางสิ่งเช่นนี้:
<?php
//Get Object Manager Instance
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
//Load product by product id
$product = $objectManager->create('Magento\Catalog\Model\Product')->load($id);
แทนที่จะผ่านขั้นตอนที่เจ็บปวด แต่แนะนำให้ทำดังนี้:
- สร้างโมดูล
- ประกาศค่ากำหนด
- ฉีดพึ่งพา
- ประกาศวิธีการสาธารณะ
อย่างไรและนี่มาขึ้นเขียง, ไฟล์วีโอไอพี 2 หลักมักจะเรียก ObjectManager โดยตรง ตัวอย่างอย่างรวดเร็วสามารถพบได้ที่นี่: https://github.com/magento/magento2/blob/develop/app/code/Magento/GoogleOptimizer/Block/Adminhtml/Form.php#L57
ดังนั้นนี่คือคำถามของฉัน:
- ทำไมวีโอไอพีถึงทำในสิ่งที่พวกเขาแนะนำเราไม่ให้ทำ หมายความว่ามีบางกรณีที่เราควรใช้
ObjectManager
โดยตรงหรือไม่ ถ้าเป็นเช่นนั้นกรณีเหล่านี้คืออะไร? - อะไรคือผลของการใช้ ObjectManager โดยตรง ?
The intent of zend-servicemanager is for use as an Inversion of Control container. It was never intended as a general purpose service locator [...]
บิตที่เกี่ยวข้องของมันจะเป็น ซึ่งมันใช้กับ M2 ได้เช่นกัน ตรวจสอบThere are valid use cases
ส่วนที่ใช้กับที่นี่อีกครั้ง