क्यों संरक्षित तरीकों को बाधित नहीं किया जा सकता है?


14

मैं सोच रहा था कि protectedतरीकों के लिए प्लगइन्स बनाना संभव क्यों नहीं है । इसमें इस कोड का टुकड़ा है Magento\Framework\Interception\Code\Generator\Interceptor:

protected function _getClassMethods()
{
    $methods = [$this->_getDefaultConstructorDefinition()];

    $reflectionClass = new \ReflectionClass($this->getSourceClassName());
    $publicMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
    foreach ($publicMethods as $method) {
        if ($this->isInterceptedMethod($method)) {
            $methods[] = $this->_getMethodInfo($method);
        }
    }
    return $methods;
}

यह जाँचता है कि क्या विधि publicइसे बाधित करने की अनुमति देने से पहले है। यह आसानी से एक बनाने के द्वारा बदला जा सकता है preferenceमें di.xmlनिश्चित रूप से, खुद मॉड्यूल के, इस तरह:

<?xml version="1.0"?>
<config>
    <preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>

और विधि के अंदर परिवर्तित के _getClassMethodsसाथ फिर से लिखना ।\ReflectionMethod::IS_PUBLIC\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED

लेकिन मुझे आश्चर्य है कि मूल विधि परिभाषा में संरक्षित विधियों को रोकना क्यों संभव नहीं है? क्या यह प्रदर्शन पर एक बड़ा प्रभाव डालता है, या इसके लिए कोई अन्य कारण है, जैसे कि 3 पार्टी मॉड्यूल को मैगेंटो लॉजिक को भी "गड़बड़" बनाने की अनुमति है?

जवाबों:


24

Magento डॉक्स के अनुसार संरक्षित विधि पर एक प्लगइन का उपयोग करना "संभव नहीं" है।

( http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html )

आप प्लगइन्स लागू नहीं कर सकते हैं:

  • अंतिम विधियाँ
  • अंतिम कक्षाएं
  • कोई भी वर्ग जिसमें कम से कम एक अंतिम सार्वजनिक तरीका हो
  • गैर-सार्वजनिक तरीके
  • कक्षा विधियाँ (जैसे स्थैतिक विधियाँ)
  • वर्चुअल प्रकार __construct

लेकिन आपकी बात सही है, ___callPluginsपरिभाषा के अनुसार Magento\Framework\Interception\Interceptor, मुझे संरक्षित तरीकों का उपयोग करने में कोई समस्या नहीं दिखती है।

मेरा पहला अनुमान है कि वे इसे एक उच्च कोड जटिलता से बचने के लिए सीमित करते हैं क्योंकि मैगेंटो को किसी भी संरक्षित विधि को फिर से लिखना चाहिए और ___callPluginsउनमें से प्रत्येक के लिए कॉल करना चाहिए ... यह IMHO को बहुत धीमा कर देगा।

लेकिन मुझे लगता है कि असली कारण तार्किक संगति के लिए है: प्लगइन्स का उपयोग क्लास के तरीकों के आउटपुट / इनपुट को बदलने के लिए किया जाना चाहिए , आंतरिक व्यवहार को फिर से लिखने के लिए नहीं, इसलिए उन्हें केवल सार्वजनिक तरीकों का उपयोग करना चाहिए।

एक आंतरिक व्यवहार को फिर से लिखने के लिए आपको एक प्राथमिकता का उपयोग करना होगा। यह समझ में आता है।


1
अच्छा उत्तर। मैं खुद भी यह सोच रहा था, लेकिन एक OOP / SOLID दृष्टिकोण से यह केवल सार्वजनिक तरीकों को बाधित करने की अनुमति देने के लिए समझ में आता है।
गेल बर्कर्स

13

अगर मुझे एंटोन क्रिल की एक प्रस्तुति से सही ढंग से याद है, तो उन्होंने कहा कि तकनीकी रूप से संरक्षित तरीकों को बाधित किया जा सकता है, लेकिन यह उन्हें "संरक्षित" होने के उद्देश्य को हरा देता है।
इंटरसेप्टर वर्ग जिसे ऑटोजेनरेटेड किया जाता है, मूल वर्ग को विस्तारित करता है, ताकि इसकी संरक्षित विधियों तक पहुंच हो।
लेकिन ... संरक्षित तरीके कक्षा के बाहर उपलब्ध नहीं होने चाहिए।
इसलिए यह एक सीमा से अधिक निर्णय है।


-4

यह OOPS सुरक्षा सुविधा है जो मैगनेटो विशिष्ट नहीं है।

सार्वजनिक तरीके, जनता द्वारा लेबल हर वर्ग के लिए उपलब्ध हैं। संरक्षित तरीकों से संरक्षित, उपवर्गों और मैत्रीपूर्ण वर्गों के लिए उपलब्ध हैं, जो एक ही पैकेज में कक्षाएं हैं। मैत्रीपूर्ण विधियाँ, कुछ भी नहीं (यानी डिफ़ॉल्ट) लेबल, मैत्रीपूर्ण कक्षाओं के लिए उपलब्ध हैं। निजी विधियाँ केवल कक्षा के लिए ही उपलब्ध हैं।

कारण:

1) संरक्षित तरीके इनहेरिटेंस दूसरे स्तर तक नहीं पहुँच सकते।

उदाहरण: एक ही पैकेज में क्लास ए और क्लास बी दो वर्गों का उदाहरण दें।

क्लास बी केवल श्रेणी ए के सार्वजनिक तरीकों के साथ-साथ विरासत में संरक्षित किया जा सकता है।


4
Protected methods... which are classes in the same package- यह सच नहीं है। संरक्षित विधियां केवल विरासत के माध्यम से एक ही पदानुक्रम में उपलब्ध कक्षाओं के लिए उपलब्ध हैं - चाहे वे एक ही पैकेज में हों या नहीं, इससे कोई फर्क नहीं पड़ता। Protected Methods can't access in Inheritence second level.- फिर से, सच नहीं है - संरक्षित विधियाँ विरासत के किसी भी स्तर पर उपलब्ध हैं, बस वस्तु दायरे के बाहर से नहीं
रोबी एवरिल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.