ম্যাজেন্টো 2: সরাসরি অবজেক্টম্যানেজারটি ব্যবহার করতে বা ব্যবহার না করার জন্য?


134

ঠিক আছে, তাই গতকাল আমরা ক্লাসে / টেমপ্লেটগুলিতে সরাসরি ব্যবহারেরObjectManager বিষয়ে ম্যাজেন্টো সম্প্রদায়ের অন্যান্য লোকদের সাথে বড় আলোচনা করেছি ।

অ্যালান কেন্টের উদ্ধৃতি দিয়ে আমরা সরাসরি অবজেক্ট ম্যানেজারটি কেন ব্যবহার না করা উচিত সে কারণগুলি সম্পর্কে আমি ইতিমধ্যে অবগত রয়েছি :

এর বেশ কয়েকটি কারণ রয়েছে। কোডটি কাজ করবে, তবে অবজেক্টম্যানেজার ক্লাসটি সরাসরি উল্লেখ না করা ভাল অনুশীলন।

  • কারণ আমরা তাই বলে! ;-) (ধারাবাহিক কোড ভাল কোড হিসাবে ভাল প্রকাশিত)
  • কোডটি ভবিষ্যতে ভিন্ন নির্ভরতা ইনজেকশন কাঠামোর সাথে ব্যবহার করা যেতে পারে
  • পরীক্ষা করা সহজ - আপনি মক অবজেক্টম্যানেজার সরবরাহ না করে প্রয়োজনীয় ক্লাসের জন্য মক আর্গুমেন্টগুলি পাস করেন
  • এটি নির্ভরতা আরও পরিষ্কার রাখে - কোডটির মাঝখানে লুকিয়ে থাকা নির্ভরতা না রেখে কোডটি কনস্ট্রাক্টর তালিকার মাধ্যমে কী নির্ভর করে তা স্পষ্ট is
  • এটি প্রোগ্রামারদের এনক্যাপসুলেশন এবং মডুলারাইজেশনের মতো ধারণাগুলি সম্পর্কে আরও ভালভাবে ভাবতে উত্সাহিত করে - যদি কনস্ট্রাক্টর বড় হয়ে যায়, তবে এটি কোডের রিফ্যাক্টরিংয়ের প্রয়োজনের একটি চিহ্ন maybe

স্ট্যাকএক্সচেঞ্জে আমি যা দেখেছি, সেখান থেকে অনেক লোক সহজ / সংক্ষিপ্ত / প্রস্তাবিত সমাধানের দিকে ঝোঁক না যেমন উদাহরণস্বরূপ:

<?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 মূল ফাইলগুলি প্রায়শই সরাসরি অবজেক্টম্যানেজারকে কল করে । একটি দ্রুত উদাহরণ এখানে পাওয়া যাবে: https://github.com

সুতরাং এখানে আমার প্রশ্নগুলি:

  • তারা কেন আমাদের না করার পরামর্শ দিচ্ছে ম্যাগেন্টো কেন? এর অর্থ কি এমন কিছু মামলা রয়েছে যেখানে আমাদের ObjectManagerসরাসরি ব্যবহার করা উচিত ? যদি তা হয় তবে সেসব মামলা কী কী?
  • সরাসরি অবজেক্টম্যানেজার ব্যবহারের পরিণতিগুলি কী কী ?


3
প্রাসঙ্গিক লিঙ্ক: mwop.net/blog/2016-04-26- অন- locators.html । এটি প্রাসঙ্গিক বিট হবে The intent of zend-servicemanager is for use as an Inversion of Control container. It was never intended as a general purpose service locator [...]। যা এটি এম 2 এর ক্ষেত্রেও প্রযোজ্য। এছাড়াও, There are valid use casesবিভাগটি যা এখানে আবার প্রযোজ্য তা পরীক্ষা করে দেখুন ।
নেভভারমাইন্ড

3
এম 2 এর বিকাশের কিছু সময় ছিল যখন ওএম ইতিমধ্যে সেখানে ছিল তবে কন্ট্রাক্টর ইঞ্জেকশন ব্যবহারের জন্য পুরো ম্যাজেন্টো এখনও পরিবর্তন হয়নি। এই মুহুর্তে অনেক লোক ম্যাজে :: getSingleton () অবজেক্টম্যানেজার :: getInstance () -> get () এর সাথে প্রতিস্থাপন করেছেন। এই জাতীয় ব্যবহারের বেশিরভাগ সময় সেই সময়ে চালু হয়েছিল। পরে সমস্ত Mage :: getSingleton () কলগুলি একটি সরঞ্জাম দ্বারা কন্সট্রাক্টর ইনজেকশন দিয়ে প্রতিস্থাপন করা হয়েছিল, কিন্তু সরঞ্জামটি ObjectManager :: getInstance () স্বীকৃতি দেয়নি, সুতরাং এটি এটি কনস্ট্রাক্টর ইঞ্জেকশন দ্বারা প্রতিস্থাপন করেনি।
আন্তন ক্রিল


3
@ তেজবাগাবনকলেপাড়ার প্রশ্ন দুটি পড়েছেন? একে অপরের কাছ থেকে অনুরূপ হওয়া অনেক দূরে রয়েছে
-15 এ ডিজিটাল পিয়ানিজম এ রাফেল

উত্তর:


98

আপনার অবজেক্টম্যানেজারটি সরাসরি ব্যবহার করা উচিত নয়!

বিধি থেকে ব্যতিক্রমগুলি হ'ল:

  • মত স্ট্যাটিক যাদু পদ্ধতিতে __wakeup, serializeইত্যাদি
  • আপনি যদি কনস্ট্রাক্টরের পিছনে সামঞ্জস্য করা উচিত
  • ইন্টিগ্রেশন পরীক্ষার ফিক্সচারগুলির মতো বিশ্বব্যাপী সুযোগে।
  • ক্লাসে যা কেবলমাত্র কারখানা, প্রক্সি ইত্যাদির মতো বস্তু তৈরির জন্য প্রয়োজন

2
আমি জানি আমার কখনই এটি সরাসরি ব্যবহার করা উচিত নয় তবে কেন ম্যাগেন্টো এটি করছে? ^^
ডিজিটাল পিয়ানিজমে রাফেল

2
আপনার উদাহরণটি পশ্চাদপদ সামঞ্জস্যের জন্য
কান্দি

এগুলি কি সর্বদা @ প্রতীকৃত হিসাবে চিহ্নিত করা হয়?
ডিজিটাল পিয়ানিজমে রাফেল


5
ওহ হ্যাঁ সাথী আমি জানি এটি কেবল বিভ্রান্তিকর। সম্ভবত তাদের বলা উচিত ছিল "এটি করবেন না তবে সচেতন থাকুন যে আমরা সম্ভবত এখানে এবং সেখানে কিছু ভুল
রেখেছি

53

সুতরাং আমরা যখন এর বিপরীতে সুপারিশ করি তখন কেন এম 2 সরাসরি অবজেক্ট ম্যানেজারকে অ্যাক্সেস করতে পারে?

নির্মম উত্তর: এম 2 এম 1 এর একটি বন্দর - সম্পূর্ণ পুনর্লিখন নয়। সুতরাং ধরে নিবেন না যে সমস্ত এম 2 কোড পুরোপুরি এখনও পোর্ট করা আছে (দুর্ভাগ্যক্রমে)। আপনি এম 2 কোড বেসে কিছু খুঁজে পাওয়ার কারণেই এর অর্থ এটি "এটি করার সর্বোত্তম উপায়" নয়। কখনও কখনও এটি কেবল "এটি এখনও ঠিক করার জন্য আমরা পাইনি"।

কম নিষ্ঠুর: অন্যান্য প্রতিক্রিয়া অনুসারে, কোনও বিকল্প নেই বলে আপনাকে কখনও কখনও এটি ব্যবহার করতে হবে। অন্যান্য সময় এটি পিছনে সামঞ্জস্যতার কারণে হতে পারে। এবং ফ্রেমওয়ার্ক কোডটি কখনও কখনও এটি সরাসরি ব্যবহার করে বোঝায়, কারণ এটি ফ্রেমওয়ার্ক কোড। তবে কোডটি না দেখে যদি আমার অনুমান করতে হয় তবে অনেকগুলি সত্যই ঠিক করা উচিত তবে এটি করার পক্ষে এটি এখনও যথেষ্ট অগ্রাধিকার পায়নি।

প্যারেন্টিংয়ের ভাল পরামর্শটি কেবল মনে রাখবেন: "বাচ্চারা, আমি যা বলি তা করুন, আমি যা করি না!"


9
চমৎকার উক্তি: বাচ্চারা, আমি যা বলি তা করুন, আমি যা করি না!
শিবকুমার


কোনও ম্যাজেন্টো 2 কী অবজেক্ট ম্যানেজার ছাড়াই নরম নির্ভরতা সমস্যা হওয়ার উপায়ের প্রস্তাব দিচ্ছে? আমার অন্যের সাথে নরম নির্ভরতা সহ একটি মডিউল রয়েছে (এটি মডিউলটি থাকলে অন্য শ্রেণিটি লোড করে)। আমি সেই শ্রেণিতে ডিআই করতে পারি না কারণ তখন ডিআই ব্যর্থ হবে। আমি এই শ্রেণীর জন্য একটি কারখানার ডিআইও করতে পারি না কারণ কারখানাটি ডিআই-তে ব্যর্থ হবে।
নাথান মেরিল

50

আপনার কখনই ব্যবহার করা উচিত নয় \Magento\Framework\App\ObjectManager::getInstance()
এটি নির্ভরতা ইনজেকশনটির উদ্দেশ্যকে পরাস্ত করে। আমরা ফিরে এসেছি Mage::getModel()
অবজেক্ট ম্যানেজারটি কেবল কারখানায় ব্যবহার করা উচিত এবং তারপরে কোনও কনস্ট্রাক্টারে ইনজেকশনের মতো।

এটি ব্যবহারের সুবিধাটি কম কোড লিখুন। তবে এটি ঠিক করে না।
এটি এখনও মূলটিতে ব্যবহৃত হয়, কারণ এটি এখনও রিফ্যাক্টর হয়নি। আমি আশা করি এটি হবে।


5
সুতরাং আমরা উভয়ই সম্মত হই যে ম্যাগেন্টো কোডটি এটি সঠিকভাবে করা হচ্ছে?
এ ডিজিটাল পিয়ানিজমে রাফেল

11
ঠিক আছে। তারা ভুল :).
মারিয়াস

আমি মনে করি না যে তারা ভুল ব্যবহার করছে। তারা যখন প্রয়োজন তখন এটি ব্যবহার করছে: যখন গতিশীল সমাধানের প্রয়োজন হয় (প্লাগিনগুলি, বিশেষত) এবং অবিলম্বে অবহেলিত পদ্ধতিগুলিতে বিসি রাখার সময়।
নেভভারমাইন্ড

2
@ নিউভারমাইন্ড একটি কারখানা ব্যবহার করে। আপনি di.xmlএকটি কী => শ্রেণীর নামের মানচিত্র তৈরি করতে এবং কারখানার নির্মাতাকে সেই মানচিত্রটি ইনজেক্ট করতে এবং ফ্যাক্টরিটি অবজেক্টম্যানেজারের মাধ্যমে শ্রেণিটি ইনস্ট্যান্ট করার জন্য ব্যবহার করেন
মারিয়াস

2
@ নিউভারমাইন্ড তবে একজন ম্যাজেন্টো কর্মচারীর মতামত আপনার মতামতকে ছড়িয়ে দেয়। কান্ডি থেকে আপনার উপরে একটি উত্তর রয়েছে যা সাহসী চিঠিতে "আপনার সরাসরি অবজেক্ট ম্যানেজারটি ব্যবহার করা উচিত নয়" তে লেখা আছে: magento.stackexchange.com/a/117103/146 আমি অনুমান করি যে এই ধরণের সমস্যাটি কুয়াশা পরিষ্কার করে দেয়।
মারিয়াস

22

তারা কেন আমাদের না করার পরামর্শ দিচ্ছে ম্যাগেন্টো কেন? তার মানে কি এমন কিছু মামলা রয়েছে যেখানে আমাদের সরাসরি অবজেক্টম্যানেজারটি ব্যবহার করা উচিত? যদি তা হয়, তবে সেসব মামলা কী?

এখানে পুরো গল্পটি না জেনে আমার অনুমান:

M2 নির্মাণের সময় কিছু পর্যায়ে Magento দলের একটি স্বয়ংক্রিয় স্ক্রিপ্ট যার ঘটনা প্রতিস্থাপন করা দৌড়ে Mage:getModel(), Mage::getSingleton(), $layout->createBlock(), ইত্যাদি ObjectManager ব্যবহার করতে।

পরবর্তী রিফ্যাক্টরিংয়ের পরিবর্তে সঠিক নির্ভরতা ইনজেকশন ব্যবহারের জন্য এটি ঠিক করা উচিত ছিল তবে সমস্ত উপস্থিতি রূপান্তর করতে পর্যাপ্ত সময় / সংস্থান ছিল না।

এছাড়াও ম্যাজেন্টো টিম ইদানীং এটিকে একটি পালানোর ব্যবস্থা হিসাবে ব্যবহার করবে বলে মনে হচ্ছে। বিদ্যমান বাস্তবায়ন ভঙ্গ করার পরিবর্তে (কনস্ট্রাক্টর পরিবর্তন করার প্রয়োজনে) কেবলমাত্র অবজেক্টম্যানেজারের মাধ্যমে তারা নতুন নির্ভরতা আড়াল করে। আমি এই পদ্ধতির সাথে একমত বলে বলতে পারি না - একটি বিসি বিরতি এড়াতে আরও খারাপ কোড লেখা।

অবজেক্টম্যানেজার সরাসরি ব্যবহারের সরাসরি পরিণতিগুলি কী কী?

আমি মনে করি আপনার প্রশ্নটিতে ইতিমধ্যে যথেষ্ট কারণ রয়েছে। সাধারণত এটি একটি গোপন নির্ভরতা তৈরি করে, অন্য কথায় নির্ভরতা বাস্তবায়নের বিশদগুলিতে থাকে এবং কেবল নির্মাণকারীর কাছ থেকে দৃশ্যমান হয় না।


এটি বিদ্রূপজনক কারণ জনসাধারণের কাছে প্রকাশের আগে যদি এটি যথাযথভাবে করা হত তবে বিসি মোটেও কোনও সমস্যা হত না
রবি অ্যাভারিল

12

সরাসরি অবজেক্ট ম্যানেজার ব্যবহার করা উচিত নয়!

এই ক্ষেত্রে:

\Magento\Framework\App\ObjectManager::getInstance();

এছাড়াও যদি আপনি ইভেন্ট পর্যবেক্ষক বা প্লাগইনগুলির সাথে কাজ করছেন তবে আপনার কখনই এটি সরাসরি ব্যবহার করা উচিত নয়।

আপনি এটি কারখানাগুলিতে ব্যবহার করতে পারেন, তবে প্রথমে আপনার কনস্ট্রাক্টরে অবজেক্ট ম্যানেজারটি ইনজেক্ট করা উচিত তবে আপনি এটির পদ্ধতিটি আপনার পদ্ধতিতে ব্যবহার করতে পারেন

ব্যবহার পছন্দসই:

1) ব্যক্তিগত অবজেক্ট ঘোষণা:

private $_objectManager;

2) কনস্ট্রাক্টর ইনজেকশন এবং আরম্ভ:

public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectmanager
) {
    $this->_objectManager = $objectmanager;
}

3) কিছু পদ্ধতিতে ব্যবহার করুন:

public function create() {
    return $this->_objectManager->create(/* ......... */);
}

এই উত্তরটি নীচে ম্যাজেন্টো ২.২ সংস্করণের জন্য, সুতরাং দয়া করে একটি নোট নিন। নতুন ম্যাজেন্টো 2 স্ট্যান্ডার্ড অনুযায়ী এখন আমরা এমনকি অবজেক্টম্যানেজার উদাহরণটিও ব্যবহার করতে পারি না। যে কোনও ডেটা পেতে আমাদের অবজেক্ট ক্লাসের ফ্যাক্টরি বা সংগ্রহস্থল ব্যবহার করতে হবে।


এটি এভাবে ব্যবহার করা কি একটি ভাল অনুশীলন?
enrico69

হ্যাঁ, কারণ ম্যাজেন্টো সরাসরি অবজেক্টম্যানেজার ব্যবহার করতে দেয় না, সুতরাং আপনাকে এইভাবে ব্যবহার করতে হবে!
রোনাক চৌহান

আপনার ইভেন্টগুলিতে কখনও কখনও এটি ব্যবহার করা উচিত নয় (আমার ধারণা আপনি পর্যবেক্ষক বোঝাতে চাইছেন) এবং প্লাগইনগুলি। আপনার প্রয়োজন অবজেক্টগুলি ইনজেক্ট করা উচিত, অবজেক্টম্যানেজার নয়। কেবলমাত্র কোনও কারখানায় আপনি অবজেক্টম্যানেজারটি ব্যবহার করতে পারবেন এবং তারপরে ফোন করার পরিবর্তে এটি অবশ্যই ইনজেক্ট করা উচিত::getInstance()
7:38

ডান, উত্তরটি 7 7 চ্যামে সম্পাদনা করুন
রোনাক চৌহান

কোনও উত্তর ডাউনভোট করা উপযুক্ত উপায় নয়, আপনার যদি আরও ভাল জ্ঞান থাকে তবে আপনি নিজের উত্তর যুক্ত করতে পারেন বা অন্যের কাছে আরও ভাল ধারণা এবং সহায়ক পেতে আপনি যে কোনওর উত্তর সম্পাদনা করতে পারেন। @ 7ochem
রোনাক চৌহান

10

বিকাশকারীরা সরাসরি অবজেক্ট ম্যানেজারকে ব্যবহার থেকে নিরুৎসাহিত করার মূল কারণ হ'ল অবজেক্ট ম্যানেজারের সরাসরি ব্যবহারের ফলে সংকলিত রিলিজ মোডে এক্সটেনশনটি ইনস্টলযোগ্য না হয়।

সুতরাং এটি ম্যাজেন্টো ক্লাউডের সমস্ত গ্রাহক সহ রিলিজ মোড ব্যবহার করে আপনার গ্রাহকদের জন্য বিরতি দেয়

এটি মনে হয় যুক্তিসঙ্গতভাবে বড় সংখ্যক বিকাশকারী (প্রায় 75%) তাদের এক্সটেনশানগুলি রিলিজ মোডে ইনস্টল করা যায় কিনা তা পরীক্ষা করে না, তাই ভুল অবজেক্টম্যানেজার ব্যবহারের কারণে উত্থাপিত সমস্যাগুলিতে দৌড়াবেন না।

২০১৩ সালের হিসাবে, ম্যাজেন্টো মার্কেটপ্লেস এর মাধ্যমে বিক্রি হওয়া সমস্ত এক্সটেনশনে একটি সংকলন এবং ইনস্টল পরীক্ষা চালায়। যদি আপনার এক্সটেনশানটি সরাসরি অবজেক্ট ম্যানেজারটি ব্যবহার করে তবে এটি এই পরীক্ষাগুলিতে ব্যর্থ হবে এবং আপনি এই সমস্যার সমাধান না করা এবং পুনরায় আপলোড না করা পর্যন্ত মার্কেটপ্লেস থেকে প্রত্যাখ্যান করা হবে।


2

আপনি অবজেক্টম্যানেজারের একটি অবজেক্ট তৈরি করে চেষ্টা করতে পারেন এবং অবজেক্টম্যানেজারটি সরাসরি ব্যবহার করা উচিত নয়

এমন কিছু ব্যবহার করুন,

class Example extends \Magento\Framework\View\Element\Template
{
    private $_objectManager;

    public function __construct(
        \Magento\Framework\ObjectManagerInterface $objectmanager
    ){
        $this->_objectManager = $objectmanager;
    }

    public function getExample()
    {
        $customerSession = $this->_objectManager->create("Magento\Customer\Model\Session");
        if ($customerSession->isLoggedIn()) {
            $customerData = $customerSession->getCustomer()->getData();
            /*Your logic*/
        }
    }
}

2
যদি অবজেক্ট ম্যানেজারটি সিঙ্গলটন হয় তবে এটি কেন পার্থক্য করবে?
ডোমডামব্রোগিয়া
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.