ম্যাজেন্টো 2: প্রক্সি ক্লাস কি এর ব্যবহারিক ব্যাখ্যা?


17

সুতরাং, আমি তাত্ত্বিকভাবে জানি যে ম্যাজেন্টো ২-তে প্রক্সি ক্লাসটি কী I've আমি এটি সম্পর্কে দুর্দান্ত অ্যালান ঝড় নিবন্ধটি পড়েছি এবং আমি কীভাবে এই ক্লাসগুলি উত্পন্ন হয় তা পুরোপুরি বুঝতে পারি।

যাইহোক, এবং আমি জানি না কারণ এটি আমি একজন অ নেটিভ ইংলিশ স্পিকার বা অ্যালানের ব্যাখ্যাগুলি নন কোর ক্লাসগুলি ব্যবহার করছে যা খুব বিমূর্ত, তবে এটি কীভাবে কাজ করে এবং বিশেষত কখন ব্যবহার করতে হবে তা বোঝার জন্য আমার খুব কষ্ট হচ্ছে এটি উন্নয়নের সময়।

সুতরাং আসুন কোর থেকে এই উদাহরণটি নেওয়া যাক app/code/Magento/GoogleAdwords/etc/di.xml:

<?xml version="1.0"?>
<!--
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\GoogleAdwords\Observer\SetConversionValueObserver">
        <arguments>
            <argument name="collection" xsi:type="object">Magento\Sales\Model\ResourceModel\Order\Collection\Proxy</argument>
        </arguments>
    </type>
</config>

আমি জানতে চাই:

  • কেন একটি প্রক্সি ক্ষেত্রে একটি প্রক্সি ক্লাস ব্যবহার করা হয়?
  • কখন, সাধারণভাবে একজনের প্রক্সি ক্লাস ব্যবহার করা উচিত?

উত্তর:


17

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

প্রক্সি শ্রেণিটি কেবল তখনই ব্যবহার করা উচিত যখন আপনি কোনও ব্যয়বহুল ক্রিয়াকলাপ চালান object সিমফনি কনসোল কমান্ডগুলির একটি ভাল উদাহরণ:

ভাবুন আপনার কনসোল কমান্ডটি প্রোডাক্ট রিপোসিটরিটি নির্ভরতা হিসাবে ব্যবহার করছে। পণ্য সংগ্রহস্থল নির্মাণকারী ক্যাটালগ ডাটাবেসে মাইএসকিউএল সংযোগ স্থাপন করে।

এটি প্রতিটি bin/magentoকলের অর্থ , আপনি যে আদেশটি চালাবেন তা নির্বিশেষে, সংগ্রহস্থল নির্ভরতা তাত্ক্ষণিকভাবে চালু করা হবে। সুতরাং এড়ানোর একমাত্র উপায় হ'ল প্রক্সি তৈরি করে আসল অবজেক্টের অলস তাত্পর্য ব্যবহার করা। এই ক্ষেত্রে ডাটাবেস, ক্যাটালগ ডাটাবেসের সাথে সংযোগ কেবল তখনই প্রতিষ্ঠিত হবে যখন আপনি কোনও সংগ্রহস্থল পদ্ধতি কল করবেন।

আশা করি এটি প্রক্সি ধারণাটি আরও ভালভাবে বুঝতে সহায়তা করে।


1
আমি যে উদাহরণটি বেছে নিলাম তা হ'ল সত্যই আমাকে আরও বিভ্রান্ত করেছে। আবার তাত্ত্বিকভাবে আমি ধারণাটি বুঝতে পারি। তবে আমি কী পাই না: আপনি যদি প্রতিটি কমান্ডের জন্য এটি ব্যবহার না করেন তবে কেন আপনি কনসোল কমান্ডের উপর নির্ভরশীলতা হিসাবে ProductRepository যুক্ত করবেন? এটি কেবলমাত্র আপনি যে আদেশগুলি ব্যবহার করেন তা নির্ভর করে না? আপনি যা বলেছিলেন সে অনুসারে, প্রক্সি নির্ভরতা "এড়িয়ে" যাওয়ার উপায়? তবে সেক্ষেত্রে কেন প্রথম স্থানের উপর নির্ভরতা হয়?
রাফেল ডিজিটাল পিয়ানোজমে

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

13

একটি প্রক্সি শ্রেণি আপনাকে এমন একটি শ্রেণীর নির্ভরতা-ইনজেকশন দেয় যা আপনাকে প্রয়োজনীয়ভাবে প্রয়োজন হয় না এবং এটি করার সাথে এটির একটি উচ্চ ব্যয় যুক্ত রয়েছে।

আপনি যদি ম্যাজেন্টো যেমন তৈরি করেছেন এমন একটি প্রক্সি দেখুন, যেমন \Magento\Framework\View\Layout\Proxy, আপনি দেখতে পাবেন যে এটির মূল শ্রেণীর মতো একই পদ্ধতি রয়েছে। পার্থক্যটি হ'ল প্রতিবার যখন এগুলির যে কোনওটিকে ডাকা হয়, এটি পরীক্ষা করে যে শ্রেণীর এটির প্রক্সি প্রকৃতপক্ষে ইনস্ট্যান্ট করা হয়েছে কিনা, এবং না হলে এটি তৈরি করে। (এটি একটি _getSubject()বা _getCache()পদ্ধতিতে ঘটে ))

এটি নির্ভরতা ইনজেকশনের জন্য অলস লোডিং।

আপনার শ্রেণি নির্ভরতা সর্বদা আপনার শ্রেণীর দ্বারা ব্যবহৃত না হলে আপনার একটি প্রক্সি ব্যবহার করা উচিত এবং:

  • এর নিজস্ব অনেকগুলি নির্ভরতা রয়েছে, বা
  • এর নির্মাতার সাথে রিসোর্স-নিবিড় কোড জড়িত, বা
  • এটি ইনজেকশনের পার্শ্ব প্রতিক্রিয়া রয়েছে

এর একটি ভাল উদাহরণ সেশনগুলি। অবজেক্টম্যানেজারের মাধ্যমে সেশনগুলি পাওয়া খারাপ অভ্যাস, তবে \Magento\Customer\Model\Sessionআপনার শ্রেণিটি যদি এই সেশনের সুযোগের বাইরে চলে যায় তবে (যেমন আপনি কোনও প্রশাসক পৃষ্ঠায় সীমানা গ্রাহক সেশন ইনজেকশন বলুন) সেশন ক্লাসের ইনজেকশন করা জিনিসগুলি ভেঙে দিতে পারে। \Magento\Customer\Model\Session\Proxyপরিবর্তে সেশনের প্রক্সি ইনজেকশন দিয়ে আপনি এটি পেতে পারেন , এবং যখন আপনি এটি বৈধ জানেন কেবল তখনই এটি রেফারেন্স করে। আপনি যদি এটি উল্লেখ না করেন তবে অধিবেশনটি কখনও তাত্ক্ষণিকভাবে হয় না এবং কিছুই ভাঙে না।

আপনার নির্দিষ্ট উদাহরণে di.xml, দেখে মনে হচ্ছে যে তারা প্রক্সিটি সেই নিয়ামকের কারখানার চেয়ে একটি নিয়ামককে ইনজেকশনের ন্যায্যতা দিতে ব্যবহার করেছিল। যেভাবেই হোক না কেন, প্রক্সিগুলির জন্য এটি ব্যবহার করার উদ্দেশ্যে করা হয় না এবং সেই পরিস্থিতিতে এটির সুবিধা সম্ভবত ন্যূনতম।


7

ম্যাজেন্টো 2 প্রকারের অটোজেনারেটেড প্রক্সিগুলি ডিজাইনের ভুলগুলি "ফিক্স" করতে ব্যবহৃত হতে পারে। এটা খুব সহজ হতে পারে। দুটি ব্যবহারের মামলা রয়েছে:

  1. একটি ব্যয়বহুল অবজেক্ট গ্রাফটি মোড়ানো যা নির্ভরকারীদের দ্বারা প্রতিবার প্রয়োজন হয় না।

  2. ক্লাস Aনির্ভর করে Bএবং ক্লাস Bনির্ভর করে যেখানে একটি চক্রীয় নির্ভরতা ভঙ্গ করুন A
    ইনজেকশন B\Proxyমধ্যে Aআপনাকে এগুলি করতে দেয় instantiate A, যা পালাক্রমে instantiate ব্যবহার করা যেতে পারে Bযখন এটি আসলে বাস্তব সঙ্গে ব্যবহার করা হয় Aঅবজেক্ট।

ক্ষেত্রে 1. নির্ভরতা হয় যে সবসময় ব্যবহার করা একটি সাইন যে dependee বর্গ অনেক আছে, হয়তো বা এক পদ্ধতি দ্বারা অনেক আছে। @Ivan উল্লিখিত কনসোল কমান্ড এর একটি ভাল উদাহরণ।

ক্ষেত্রে 2. আমি যে নির্ভরতা ভেঙ্গে জন্য এক জেনেরিক পন্থা জানি না। সময় থাকলে আমার আবার লেখার ঝোঁক রয়েছে, তবে এটি কোনও বিকল্প হতে পারে না।

পার্শ্ব নোট হিসাবে, আমি যুক্ত করতে চাই যে ওওপিতে আরও অনেক ধরণের প্রক্সি রয়েছে স্বয়ংক্রিয়রিত অলস তাত্ক্ষণিকতার জন্য একটি ম্যাজেন্টো 2 ব্যবহার (যেমন দূরবর্তী প্রক্সি)।


হ্যালো @ বিনাই, __constructor () পদ্ধতি বা di.xML এর মাধ্যমে প্রক্সি ক্লাসগুলি ব্যবহার করার উপায় কী?
আকোগোলা

1
ম্যাজেন্টো কোডিং গাইডলাইন অধ্যায় অনুসারে 2.5 প্রক্সি ক্লাস কন্সট্রাক্টরে ঘোষণা করা উচিত নয়। প্রক্সিগুলি di.xML এ ঘোষণা করা আবশ্যক। Devdocs.magento.com/guides/v2.3/coding- স্ট্যান্ডার্ডস

1

উত্তর এখানে দেওয়া হল

কেন একটি প্রক্সি ক্ষেত্রে একটি প্রক্সি ক্লাস ব্যবহার করা হয়?

যদি আপনি নীচের কোডটি নীচে ঘুরে দেখেন যা ক্লাস "সেটকভার্সনভালিউঅবার্সার" এর জন্য লেখা রয়েছে, যদি গুগল অ্যাডওয়ার্ডস সক্রিয় না হয় "রিটার্ন" এবং যদি কোনও আদেশ নেই "রিটার্ন"। মানে, অর্ডার সংগ্রহের অবজেক্টটি তখনই তৈরি করা হবে যখন অর্ডার আইডি উপস্থিত থাকে এবং গুগল অ্যাডওয়ার্ড সক্রিয় থাকে। যদি আমরা প্রকৃত অর্ডার সংগ্রহের ক্লাসটি ইনজেক্ট করি তবে অবজেক্ট ম্যানেজার গুগল অ্যাডওয়ার্ডগুলি সক্রিয় না করে এবং সেই অর্ডার সাফল্যের পৃষ্ঠাটি না জেনে তার পিতামাত্ত শ্রেণীর অবজেক্টের সাথে সংগ্রহ অবজেক্ট তৈরি করে। সুতরাং, চাহিদার উপর আরও ভাল তৈরি করুন যা প্রক্সি ব্যবহার। /vendor/magento/module-google-adwords/Observer/SetConversionValueObserver.php

 /**
 * Set base grand total of order to registry
 *
 * @param \Magento\Framework\Event\Observer $observer
 * @return \Magento\GoogleAdwords\Observer\SetConversionValueObserver
 */
public function execute(\Magento\Framework\Event\Observer $observer)
{
    if (!($this->_helper->isGoogleAdwordsActive() && $this->_helper->isDynamicConversionValue())) {
        return $this;
    }
    $orderIds = $observer->getEvent()->getOrderIds();
    if (!$orderIds || !is_array($orderIds)) {
        return $this;
    }
    $this->_collection->addFieldToFilter('entity_id', ['in' => $orderIds]);
    $conversionValue = 0;
    /** @var $order \Magento\Sales\Model\Order */
    foreach ($this->_collection as $order) {
        $conversionValue += $order->getBaseGrandTotal();
    }
    $this->_registry->register(
        \Magento\GoogleAdwords\Helper\Data::CONVERSION_VALUE_REGISTRY_NAME,
        $conversionValue
    );
    return $this;
}

কখন, সাধারণভাবে একজনের প্রক্সি ক্লাস ব্যবহার করা উচিত? - প্রক্সি শ্রেণীর ইনজেক্ট করুন যখন আপনি মনে করেন যে অবজেক্ট তৈরি করা ব্যয়বহুল হবে এবং শ্রেণীর নির্মাতা বিশেষত সংস্থান-নিবিড়। - যখন আপনি অবজেক্ট তৈরির কারণে অপ্রয়োজনীয় পারফরম্যান্স প্রভাবটি চান না। - যখন আপনি মনে করেন যখন নির্দিষ্ট অবস্থানে নির্দিষ্ট পদ্ধতিতে সবসময় না হয় তখন অবজেক্ট তৈরি হওয়া উচিত should উদাহরণস্বরূপ লেআউট কনস্ট্রাক্টর হ'ল একটি রিসোর্স-নিবিড়।

প্রকৃত লেআউট কনস্ট্রাক্টর বনাম লেআউট / প্রক্সি

public function __construct(
    Layout\ProcessorFactory $processorFactory,
    ManagerInterface $eventManager,
    Layout\Data\Structure $structure,
    MessageManagerInterface $messageManager,
    Design\Theme\ResolverInterface $themeResolver,
    Layout\ReaderPool $readerPool,
    Layout\GeneratorPool $generatorPool,
    FrontendInterface $cache,
    Layout\Reader\ContextFactory $readerContextFactory,
    Layout\Generator\ContextFactory $generatorContextFactory,
    AppState $appState,
    Logger $logger,
    $cacheable = true,
    SerializerInterface $serializer = null
) {
    $this->_elementClass = \Magento\Framework\View\Layout\Element::class;
    $this->_renderingOutput = new \Magento\Framework\DataObject();
    $this->serializer = $serializer ?: ObjectManager::getInstance()->get(SerializerInterface::class);

    $this->_processorFactory = $processorFactory;
    $this->_eventManager = $eventManager;
    $this->structure = $structure;
    $this->messageManager = $messageManager;
    $this->themeResolver = $themeResolver;
    $this->readerPool = $readerPool;
    $this->generatorPool = $generatorPool;
    $this->cacheable = $cacheable;
    $this->cache = $cache;
    $this->readerContextFactory = $readerContextFactory;
    $this->generatorContextFactory = $generatorContextFactory;
    $this->appState = $appState;
    $this->logger = $logger;
}

প্রক্সি কন্সট্রাক্টর, একবার দেখুন, কোনও পিতামাতৃ কনস্ট্রাক্টর কল করা হয়নি পাশাপাশি সবেমাত্র বিন্যাস শ্রেণীর নামটিও পাস করেছেন যাতে পদ্ধতি বলা হলে প্রকৃত অবজেক্ট তৈরি হয় creation

 /**
 * Proxy constructor
 *
 * @param \Magento\Framework\ObjectManagerInterface $objectManager
 * @param string $instanceName
 * @param bool $shared
 */
public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectManager,
    $instanceName = \Magento\Framework\View\Layout::class,
    $shared = true
) {
    $this->_objectManager = $objectManager;
    $this->_instanceName = $instanceName;
    $this->_isShared = $shared;
}

প্রক্সি ক্লাসে চাহিদার ভিত্তিতে অবজেক্ট তৈরি করার পদ্ধতি রয়েছে, _সুবজেক্টটি উত্তীর্ণ শ্রেণীর অবজেক্ট।

/**
 * Get proxied instance
 *
 * @return \Magento\Framework\View\Layout
 */
protected function _getSubject()
{
    if (!$this->_subject) {
        $this->_subject = true === $this->_isShared
            ? $this->_objectManager->get($this->_instanceName)
            : $this->_objectManager->create($this->_instanceName);
    }
    return $this->_subject;
}

এবং পদ্ধতিটিকে _ সাবজেক্ট ব্যবহার করে ডাকা হয়।

/**
 * {@inheritdoc}
 */
public function setGeneratorPool(\Magento\Framework\View\Layout\GeneratorPool $generatorPool)
{
    return $this->_getSubject()->setGeneratorPool($generatorPool);
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.