अशुद्धियों पर मेरे लेख के जारी होने के बाद
, हमने
लेख में टिप्पणियों और निजी संदेशों में चर्चा जारी रखी। आज मैंने अपने ब्लॉग पर एक पाठक की
टिप्पणी देखी, जिसने मुझे यह बताने के लिए कहा कि मुझे
लियोनिद श्लेचर पर मेरे कार्यान्वयन का लाभ क्या है।
मैं अपनी ही साइट पर एक पोस्ट के लिए एक टिप्पणी में जवाब देने वाला था, लेकिन यह अचानक पता चला कि सवाल काफी दिलचस्प था। बल्कि, यह स्वयं प्रश्न नहीं है, बल्कि मैंने जो विश्लेषण किया, उसका उत्तर तैयार किया।
मुझे संदेह है कि लियोनिद के साथ हम दोनों में से एक ने खुद को किसी भी आकार की परियोजनाओं में अशुद्धियों के सार्वभौमिक कार्यान्वयन का कार्य निर्धारित किया है। हमारे दोनों कार्यान्वयन, यह मुझे लगता है, घर के ढांचे के स्तर से बहुत आगे नहीं जाते हैं और एक काम करने वाले उपकरण की तुलना में निष्कासन () के बिना अशुद्धियों को लागू करने के लिए एक अवधारणा के अधिक हैं। लेकिन, फिर भी, चलो तुलना में गोता लगाने की कोशिश करते हैं।
अशुद्धियों के बारे में कैश्ड जानकारी संग्रहीत करने के लिए तथाकथित रजिस्ट्री के उपयोग के कारण मेरा संस्करण अधिक उत्पादक है। लेकिन मेरे द्वारा उपयोग किया जाने वाला कैशिंग विकल्प केवल तभी प्रभावी होता है जब अशुद्धता की विधि / संपत्ति को बार-बार एक्सेस किया जाता है। यदि पहुँच एक बार में है - तो मेरे संस्करण में यह संभवतः लियोनिद की तुलना में शालीन हो जाएगा, क्योंकि आपको पहले कैश बनाने की आवश्यकता है। इस खामी को खत्म करने के लिए, मेरे मामले में, मुझे एक स्थिर रजिस्ट्री वर्ग के एक मॉडल से एक सिंगलटन रजिस्ट्री मॉडल के लिए स्विच करना चाहिए, जिसे एक अमूर्त कारखाने के माध्यम से शुरू किया गया है, या फ्रेमवर्क स्तर के एक मानक "रजिस्ट्री" पैटर्न को लागू करना चाहिए। यह आपको परियोजना की आवश्यकताओं के आधार पर रजिस्ट्री कार्यान्वयन को अलग करने की अनुमति देगा और, उदाहरण के लिए, विधियों को एक-बार कॉल को गति देने के लिए डायरेक्ट कॉल के साथ कैशिंग को प्रतिस्थापित करें।
जैसा कि मेरे पाठक ने उल्लेख किया है, कैशिंग के कार्यान्वयन ने कोड को जटिल कर दिया और इसे और अधिक त्रुटि प्रवण बना दिया (ये खाली शब्द नहीं हैं, मैंने डिबगिंग करते समय कई कीड़े पकड़े, और यह परीक्षण लिखने के लिए बहुत आलसी था) और समझने के लिए थोड़ा अधिक कठिन था।
मुझे और लियोनिद दोनों को लगता है कि कचरा संग्रहण से संबंधित एक ही कार्यान्वयन त्रुटि हुई है। चक्रीय संदर्भों पर ध्यान दें: अशुद्धियों की कक्षाओं के संदर्भों को एक एग्रीगेटर वर्ग में संग्रहीत किया जाता है, और अशुद्धियों में, बदले में, एग्रीगेटर्स के वर्गों के उदाहरणों को संग्रहीत किया जाता है। 5.3 से पहले के PHP संस्करणों में, एक मेमोरी रिसाव होगा, क्योंकि कचरा कलेक्टर को यह नहीं पता है कि परिपत्र संदर्भों के साथ कैसे काम किया जाए। 5.3 में, आप इस उद्देश्य के लिए एक विशेष कचरा कलेक्टर को सक्रिय कर सकते हैं, लेकिन यह स्क्रिप्ट को पूरी तरह से धीमा कर देता है, इसलिए यह अवांछनीय है। उसके बारे में इतना बुरा क्या है? यह सब इस बात पर निर्भर करता है कि अशुद्धियों का उपयोग क्यों और कैसे किया जाता है। यदि उनकी अशुद्धियों के साथ बहुत सारे एग्रीगेटर ऑब्जेक्ट हैं, तो वे बड़े और जटिल हैं, जो अक्सर निर्मित / नष्ट हो जाते हैं - सब कुछ बहुत खराब होगा। यदि अशुद्धियों को एग्रीगेटर्स के साथ मिलाया जाता है जो कि स्क्रिप्ट के जीवन भर में मौजूद है, तो कुछ भी गलत नहीं होगा, क्योंकि स्क्रिप्ट द्वारा कब्जा की गई सभी मेमोरी को पूरा होने पर मुक्त करने के लिए मजबूर किया जाएगा।
इस त्रुटि को कैसे ठीक करें? दोनों कार्यान्वयन में, ऐसा करने के लिए काफी सरल है, जो कि बहुत बार इस्तेमाल नहीं किए गए PHP अवसर - विध्वंसक का लाभ उठाता है। एक विध्वंसक को जोड़ने के लिए आवश्यक है, प्रवेशकर्ता वर्ग में संदर्भ को जबरन शून्य करने के लिए, एग्रीगेटर वर्ग में एक संहारक और एक विध्वंसक, जो इस वर्ग की अशुद्धियों की सूची को साफ करता है।
अब यह पता चला है कि लियोनिद का संस्करण बिल्कुल भी संकलन नहीं करता है, क्योंकि कॉलर वर्ग में जादू __call () विधि संरक्षित नहीं की जा सकती है। ठीक किया, कमाया।
टिप्पणी के संस्करण 5.3 में
, यह त्रुटि अब मौजूद नहीं है।
लियोनिद ने अशुद्धता में जादू के तरीकों को लागू किया ताकि अशुद्धता एग्रीगेटर वर्ग के सदस्यों को अपने रूप में संदर्भित कर सके। मुझे ऐसा करने का अनुमान नहीं था। हालांकि, मैं इस विचार को घर पर लागू करने के बारे में सोचूंगा। अब तक, मैं वास्तव में कॉल ग्राफ़ को पसंद नहीं करता हूं, जो एक ही समय में प्राप्त होता है, और गुंजाइश की कुछ अस्पष्टता।
लियोनिद संस्करण स्थिर है। किसी कारण के लिए, कोड लिखा जाता है ताकि एग्रीगेटर के निर्माण में अशुद्धियों को बनाने की आवश्यकता हो, जो सामान्य रूप से, अशुद्धियों की अवधारणा का थोड़ा विरोधाभास करता है। मेरे संस्करण में, अशुद्धियाँ गतिशील रूप से कक्षाओं से जुड़ी होती हैं, और इसके लिए स्वयं कक्षाओं को लोड करने की आवश्यकता नहीं होती है (न तो एग्रीगेटर, और न ही अशुद्धियाँ)। यही है, प्रदर्शन के त्याग के बिना परियोजना के एक स्थान पर सभी अशुद्धियों को जोड़ा जा सकता है। इसका भी दोष है: एग्रीगेटर वर्ग या अशुद्धता के नाम पर एक त्रुटि को ट्रैक करना अधिक कठिन है। आखिरकार, कक्षाएं तब तक लोड नहीं होती हैं जब तक वे वास्तव में उपयोग नहीं किए जाते हैं।
लियोनिद के प्रकार में असमानताओं को विशेष रूप से विरासत द्वारा महसूस किया जाता है। मेरे संस्करण में, रचना, विरासत के साथ भी उपलब्ध है। यह कभी-कभी उपयोगी होता है यदि वर्ग को एग्रीगेटर वर्ग से विरासत में प्राप्त नहीं किया जा सकता है।
मेरे संस्करण में "कनेक्शन" के कारण, मुख्य कोड के निष्पादन के दौरान अशुद्धियों को सीधे कक्षाओं से जोड़ा जा सकता है। यही है, अगर आप सावधानी बरतते हैं, तो यह पता चल सकता है कि यह प्रवेश कक्षा के एक उदाहरण में मिलाया गया है, और दूसरे से नहीं। हमने अत्यधिक लचीलापन प्राप्त किया है, जो यदि आवश्यक हो तो समाप्त करना आसान है। वैसे, यह कैश (रजिस्ट्री) की जांच करके किया जा सकता है।
लियोनिद का संस्करण एक एग्रीगेटर वर्ग के सभी जादू के तरीकों को लागू नहीं करता है (मुख्य जोर तरीकों पर है), लेकिन इसे ठीक करना आसान है।
हमारे दोनों विकल्प समान नाम के साथ अशुद्धता तरीकों की उपस्थिति के साथ स्थिति के लिए समान रूप से प्रतिक्रिया करते हैं: पहली अशुद्धता विधि कहा जाएगा। मेरी राय में, यह भी सही विकल्प नहीं है। हालांकि, सत्यापन का कार्यान्वयन कुछ महंगा है, खासकर ऐसे मामलों में जहां अशुद्धियों को जल्दी से प्रदर्शन करने की आवश्यकता होती है: इस एग्रीगेटर के लिए सभी वर्गों की अशुद्धियों को लोड किए बिना डुप्लिकेट की उपस्थिति को सत्यापित करना असंभव है। इसलिए ऐसा लग रहा है कि हम दोनों ने इसके साथ जुड़ने का फैसला किया है।
लियोनिद स्थिति में त्रुटियों के लिए एक चेक जोड़ने के लिए भूल गया, अगर एक nox नाम के साथ एग्रीगेटर विधि को लागू करने के लिए खुद के माध्यम से प्रयास किया जाता है। यह बुरा है, क्योंकि परिणामी कार्यान्वयन में कोई गलत स्थिति नहीं है और सिर्फ कुछ भी नहीं होता है। या शायद ऐसा माना जाता था? सामान्य तौर पर, मेरे दृष्टिकोण से, यह बुरा है। बेहतर है कि एक त्रुटि हो। हालांकि, सब कुछ आसानी से तय हो जाता है।
लियोनिद के पास एक और उत्सुक स्थिति है यदि कोई अशुद्धता में किसी नाम से संरक्षित या निजी पद्धति को परिभाषित करता है, और फिर एग्रीगेटर पर उस नाम के साथ एक विधि को कॉल करने की कोशिश करता है। कॉल ग्राफ पर ध्यान दें। __Call () को एग्रीगेटर पर बुलाया जाता है, मेथड_एक्सिस्ट्स () का उपयोग करके अशुद्धता विधियों के बीच दिए गए नाम के साथ विधि की खोज की जाती है। एक मिलान का पता लगाया जाता है क्योंकि छिपे हुए और संरक्षित सदस्यों के लिए method_exists () भी सही है। इस पद्धति को पहले से ही अशुद्धता उदाहरण पर कॉल करने का प्रयास किया जाता है। चूँकि विधि इस दायरे से अभी तक संरक्षित और अप्राप्य है, इसलिए __call () जादू अशुद्धता विधि पहले से ही कहा जाता है, जो बदले में, __access_call छद्म-जादू एग्रीगेटर विधि को कॉल करता है, क्योंकि लियोनिद त्रुटि जाँच जोड़ना भूल गया था। चूंकि कोई त्रुटि जाँच नहीं है, कुछ भी नहीं होता है और हमें कोई त्रुटि नहीं मिलती है, हालाँकि मैं व्यक्तिगत रूप से चाहूंगा। हां, और ग्राफ ही जटिल था, मेरी राय में, 80 लाइनों पर अशुद्धियों के कार्यान्वयन के लिए ... यह, ज़ाहिर है, एक गलती को ठीक करने के लिए आसान है।
लेख पर एक टिप्पणी में, लेखक का उल्लेख है कि "प्रत्येक माता-पिता वर्ग को अपनी सभी अशुद्धियों के उदाहरण बनाने होंगे। हालांकि, वह सभी उदाहरणों का उपयोग कर सकते हैं, उन्हें रजिस्ट्री का उपयोग करके प्राप्त कर सकते हैं। ” इस मामले में, रजिस्ट्री के माध्यम से तैयार प्रतियां प्राप्त करना सुविधाजनक है केवल अगर अशुद्धियों का अपना राज्य नहीं है। अन्यथा, विचार अपना अर्थ खो देता है और आपको दूसरे तरीके की तलाश करने की आवश्यकता होती है।
साइट पर टिप्पणियों में, लेखक का उल्लेख है कि उसने स्थिर अशुद्धता के तरीकों के लिए समर्थन जोड़ा। मेरे संस्करण में, स्थैतिक तरीकों के लिए रजिस्ट्री में अतिरिक्त कैश बनाने की आवश्यकता है। थोड़ा और शरीर की हरकत। अभी के लिए, मैं शायद बचना चाहूंगा।
यह ध्यान दिया जाना चाहिए कि लियोनिद के कार्यान्वयन में एग्रीगेटर के छद्म-जादुई तरीके शामिल हैं, जो वास्तव में सार्वजनिक इंटरफ़ेस में वर्ग के छिपे हुए और संरक्षित सदस्यों तक पहुंच प्राप्त करते हैं। बेहतर या बदतर के लिए, यह परियोजना पर निर्भर करता है। सिद्धांत रूप में, सामान्य प्रोग्रामर को पहले से ही समझना चाहिए कि दो अंडरस्कोर से शुरू होने वाले तरीके सिस्टमिक, आंतरिक चीजें करते हैं और इसे केवल रूपरेखा के अंदरूनी हिस्सों से बुलाया जाना चाहिए। तो, यह एक विशेष समस्या नहीं है।
मैं अतिरिक्त चेक के लिए पीएचपी में टाइपिंगिंग का सक्रिय रूप से उपयोग करता हूं। लियोनिद ने ध्यान नहीं दिया, लेकिन यह कुछ भी नहीं है।
PHP 5.3 में, स्थिर कॉल के लिए अशुद्धियों की सूची के साथ एक स्थिर संपत्ति को
टिप्पणी पृष्ठ पर जोड़ा गया है। मुझे लगता है कि यह कुछ हद तक संदर्भ से बाहर है, क्योंकि पहली नज़र में ऐसा लगता है कि अशुद्धियों को स्थिर और उदाहरण में विभाजित किया गया है, जो सच नहीं है।
वैसे, लेखक का संस्करण पहले से ही परियोजना में काम कर रहा है, लेकिन मेरा अभी तक नहीं है। अपने कंप्यूटर पर बेकार ...
अप्रासंगिक से, मैं नोट कर सकता हूं जब आप साइट पर कोड पढ़ते हैं, तो मैं यह देखना चाहूंगा कि क्या
सिंटैक्स को
रंग में हाइलाइट नहीं किया
गया है , तो कम से कम ताकि इंडेंटेशन सामान्य हो। विश्लेषण के लिए लियोनिद के कोड को ज़ेंड स्टूडियो में प्रारूपित किया जाना था। अगर बाहरी लोगों द्वारा विश्लेषण के लिए साइट पर कोड का इरादा नहीं था, तो मैं माफी मांगता हूं। केवल एक चीज जो मुझे उत्तेजित करती है वह यह है कि यह खुले स्रोतों से प्राप्त की जाती है।
लियोनिद की साइट पर टिप्पणियों में, नियमित प्रतिनिधिमंडल पर अशुद्धियों के लाभों के बारे में एक सवाल भी पूछा गया था, लेकिन यह मेरे अगले लेख के लिए एक विषय है, जिसमें अधिक समय नहीं लगेगा। वॉल्यूम मुझे इस मुद्दे पर अपनी बात कहने की अनुमति नहीं देता है।
टिप्पणियों में एक विशाल अनुरोध "खराब / अच्छा" के संदर्भ में दो कार्यान्वयन की तुलना नहीं करने के लिए। अपना सम्मान करें। फायदे और नुकसान के बारे में बोलते हुए, demagoguery से बचना चाहिए। तथ्य, तथ्य और तथ्य फिर से। ट्रोल जो "यूजी" और "केजी / एएम" चिल्लाना पसंद करते हैं, यहां तक कि इस मुद्दे को समझने के बिना,
लैंडिंग पर जाने के
लिए कहा
जाता है , ट्रेन जल्द ही रवाना होगी।
आपका ध्यान देने के लिए धन्यवाद।