2010-03-27 11 views
6

क्या आपको Zend_Registry उपयोगी लगता है?Zend_Registry: वास्तविक जीवन उदाहरण

किस कार्यों के लिए इसका उपयोग किया जाना चाहिए? जिसके लिए नहीं?

चर के लिए वैश्विक स्थिति एक अच्छा अभ्यास नहीं है। मुख्य वस्तुओं में $front->setParam('paramName', $object), के माध्यम से वैश्विक स्थिति इंजेक्शन हो सकती है तो Zend_Registry का उद्देश्य क्या है?

+3

आपको 'Zend_Registry :: getInstance() '-singelton से' Zend_Registry' को अलग करना चाहिए। क्लास को वैश्विक रूप से जेडएफ में आंतरिक रूप से इस्तेमाल किया जाता है, इसलिए 'ज़ेंड_ रजिस्ट्री'! = वैश्विक। – chelmertz

उत्तर

9

PoEAA on Registry Pattern का हवाला देते हुए:

आप एक वस्तु आप आमतौर पर किसी अन्य वस्तु इसे करने के लिए एक संघ है कि के साथ शुरू, और संघ इसे करने के लिए नेविगेट करने के लिए उपयोग करना चाहते हैं जब। इस प्रकार, यदि आप किसी ग्राहक के लिए सभी ऑर्डर ढूंढना चाहते हैं, तो आप ग्राहक ऑब्जेक्ट से शुरू करते हैं और आदेश प्राप्त करने के लिए उस पर एक विधि का उपयोग करते हैं। हालांकि, कुछ मामलों में आपके पास शुरू करने के लिए उचित वस्तु नहीं होगी। आप ग्राहक के आईडी नंबर को जान सकते हैं लेकिन संदर्भ नहीं है। इस मामले में आपको किसी प्रकार की लुकअप विधि की आवश्यकता होती है - एक खोजक - लेकिन सवाल बनी हुई है: आप खोजक को कैसे प्राप्त करते हैं?

मुख्य कारण मैं रजिस्ट्री (जब मैं इसका इस्तेमाल) क्योंकि यह एक आसानी से सुलभ आवेदन गुंजाइश बनाता है का उपयोग करें। रजिस्ट्री के साथ, मुझे वैश्विक स्तर पर ऑब्जेक्ट्स को कूड़ेदान की ज़रूरत नहीं है; केवल रजिस्ट्री ही वैश्विक है। यह देखने जो कुछ भी मैं रजिस्ट्री में हर जगह से फेंक दिया गया है मॉडल सहित, के लिए सुविधाजनक है:

  • Zend_Cache, Zend_Translate, महत्वपूर्ण अनुप्रयोगों पथ, आदि

हालांकि, सिर्फ Singletons साथ की तरह, रजिस्ट्री अक्सर है असहमति प्रकट करना। यहां एक article by Brandon Savage with some thought about why not to use the Registry है। रजिस्ट्री के खिलाफ मुख्य तर्क हैं

  • यह बनाता है इकाई परीक्षण कठिन
  • अनुभवहीन कोडर इसे में बहुत ज्यादा फेंक सकती है और उचित डिजाइन के बारे में परवाह नहीं है

जो लोग रजिस्ट्री खिलाफ वोट आम तौर पर Dependency Injection के उपयोग की वकालत करते हैं, हालांकि यह ध्यान दिया जाना चाहिए कि एक बार जब आप इसका उदाहरण प्राप्त कर लेंगे तो आप भी रजिस्ट्री इंजेक्ट कर सकते हैं। आपके पास Inversion of Control नहीं है, हालांकि, उपयोग करने वाली वस्तु रजिस्ट्री से इसकी आवश्यकता को खींचती है। सेवा लोकेटर के रूप में रजिस्ट्री का उपयोग करना एक वैध दृष्टिकोण है।

यह article by Martin Fowler about ServiceLocator vs. Dependency Injection देखें।

आपके प्रश्न पर टिप्पणियों की ओर इशारा करते हुए, Zend_Registry सख्त सिंगलटन नहीं है। आप Zend_Registry::getInstance() के साथ प्राप्त होने वाले वैश्विक उदाहरण का उपयोग करने के अतिरिक्त आवश्यक कई उदाहरणों को तुरंत चालू कर सकते हैं। तो वस्तुओं की अपनी रजिस्ट्री हो सकती है। लेकिन इस तरह रजिस्ट्री का उपयोग करते समय, यह मूल रूप से केवल एक गौरवशाली ArrayObject है।

अंतिम नोट: बस सभी डिज़ाइन पैटर्न के साथ, अपनी समस्या पर लागू होने पर इसका उपयोग करें।

10

जब आप $front->setParam का उपयोग कर रहे हैं, तो आप फ्रंट कंट्रोलर में पैरामीटर को परिभाषित कर रहे हैं।

लेकिन यह पैरामीटर (या इसका उपयोग नहीं किया जाना चाहिए) मॉडल के अन्य परतों जैसे मॉडल में उपलब्ध नहीं है।

Zend_Registry, किसी अन्य वैश्विक चर की तरह, आपके आवेदन में कहीं से भी उपलब्ध है - मॉडल के अंदर भी।

लेकिन वैश्विक चर का एक समूह के बजाय एक रजिस्ट्री का उपयोग कर यह सुनिश्चित करता है कि आप कई वैश्विक चर हर जगह नहीं होगी, जो भले ही एक रजिस्ट्री का उपयोग कर कुछ वैश्विक राज्य का तात्पर्य (जो कि अच्छा नहीं है, एक कहना चाहिए), यह यह सब एक ही स्थान पर बेहतर है।


वास्तविक जीवन उदाहरण के एक जोड़े को हो सकता है:

  • स्टोर डेटाबेस है, जो bootsreap में स्थापित किया गया है, लेकिन मॉडल
  • विश्व स्तर पर प्रयोग किया जाता है एक एडाप्टर स्टोर करने के लिए कनेक्शन (या किसी भी mecanism) जिसका उपयोग आपके आवेदन की सभी परतों में अनुवाद/स्थानीयकरण करने के लिए किया जाएगा - ज़ेंड फ्रेमवर्क स्वयं ही करता है।


अंत में, मैं Zend_Registry उपयोगी पाते हैं?

ठीक है, जब कुछ वैश्विक स्थिति होने की बात आती है, हाँ, यह उपयोगी है।

लेकिन यदि इसका उपयोग टाला जा सकता है, तो यह बेहतर हो सकता है: अवधारणात्मक रूप से बोलना, आपकी कक्षा किसी भी वैश्विक स्थिति पर निर्भर नहीं है बेहतर: पुन: उपयोग करने में आसान, परीक्षण करने में आसान, ...
इसके बारे में, आप Dependency Injection पर एक नज़र डालना चाहते हैं।

+0

$ front-> सेट पैराम निर्भरता इंजेक्शन नहीं है? ज़ेंड एप्लिकेशन संसाधनों के बारे में क्या? – takeshin

4

मैं Pascal MARTIN से सहमत हूं। मैंने खुद को निर्भरता इंजेक्शन में खुद को आदी करना शुरू कर दिया। लेकिन मुझे नियंत्रकों में वस्तुओं को इंजेक्ट करने का कोई तरीका नहीं मिला है, इसलिए मैंने हाल ही में जो किया वह नियंत्रक में किसी सेवा तक पहुंचने के लिए रजिस्ट्री का उपयोग करता था। एक मौजूदा परियोजना में मैं कर रहा हूँ निम्नलिखित:

बूटस्ट्रैप:

// simple DI without an IoC container, and what have you 
$dbAdapter = Zend_Db::factory(/* bla bla */); 
$mediaService = new Service_Media(new Repository_Media_Db($dbAdapter)); 
$registry  = Zend_Registry::getInstance(); 
$registry->mediaService = $mediaService; 

... तो एक नियंत्रक में:

public function init() 
{ 
    $this->_mediaService = Zend_Registry::get('mediaService'); 
} 

public function listAction() 
{ 
    // simplified 
    $this->view->media = $this->_mediaService->listAllUploadedVideos(); 
} 

उम्मीद है कि इस के लिए एक उपयोगी उदाहरण है आप।

+0

क्या रजिस्ट्री को वास्तव में यहां जरूरी है? एक्शन हेल्पर पर्याप्त नहीं होगा? – takeshin

+0

मैं आमतौर पर क्या करता हूं: _initMediaService() {वापसी $ सेवा;} ;, फिर कार्रवाई नियंत्रक में: $ front-> getParam ('MediaService'); – takeshin

+0

एक्शन हेल्पर भी मुझे लगता है कि एक अच्छा विकल्प है। यह है ... जब तक यह केवल एक नियंत्रक में आवश्यक है। लेकिन आपके पास ऐसी स्थिति हो सकती है जहां इस सेवा की किसी अन्य सेवा या व्यावसायिक परत में भी आवश्यकता हो। हालांकि मुझे लगता है कि फिर से कन्स्ट्रक्टर इंजेक्शन द्वारा इसका ख्याल रखा जा सकता है। हम्म ..जैसा कि आप देख सकते हैं, मैंने अभी तक बहुत अधिक गहराई में इसके बारे में सोचा नहीं है। अब तक यह उदाहरण मेरे उद्देश्यों के अनुरूप है। मुझे लगता है कि कार्य पूरा करने के कई तरीके हैं। यह सब इस बात पर निर्भर करता है कि मुझे लगता है कि कितने शुद्धवादी आपसे संपर्क करना चाहते हैं। जैसे ही मैं डीआई में थोड़ा और खोदता हूं, मैं शायद इस दृष्टिकोण को हटा दूंगा। –

संबंधित मुद्दे