2010-01-20 22 views
10

मैं अब PHP कक्षाओं और वस्तुओं के साथ काम कर रहा हूं। इस प्रश्न में खेतों और विधियों के नाम बस बनाए गए हैं ताकि आपको पता चल सके कि मैं किस बारे में बात कर रहा हूं।रजिस्ट्री या सिंगलटन पैटर्न?

यह सिंगलटन और रजिस्ट्री डिज़ाइन पैटर्न का उपयोग करने से संबंधित है।

अब कहें कि मुझे डेटाबेस ऑब्जेक्ट, कैश ऑब्जेक्ट, कोर सेटिंग्स ऑब्जेक्ट, सत्र ऑब्जेक्ट को लगभग हर दूसरे वर्ग में एक्सेस करने की आवश्यकता है, मुझे इन तक पहुंच की आवश्यकता होगी। इसलिए मैं उन सभी 4 ऑब्जेक्ट्स को 1 रजिस्ट्री क्लास ऑब्जेक्ट में स्टोर करने के लिए रजिस्ट्री का उपयोग करूंगा। मैं फिर आसानी से अपने 1 ऑब्जेक्ट में किसी अन्य ऑब्जेक्ट में पास कर सकता था जिसे इन तक पहुंचने की आवश्यकता होती है। तो यह अब तक बहुत अच्छा लगता है, लेकिन अगर मेरे पास कुछ कक्षाएं हैं जिन्हें उन सभी 4 वस्तुओं की आवश्यकता नहीं है, तो क्या होगा यदि मुझे केवल कुछ अन्य वर्गों में डेटाबेस ऑब्जेक्ट या सत्र ऑब्जेक्ट तक पहुंचने की आवश्यकता है? लाभ के लिए इन अन्य वस्तुओं के अंदर केवल एक सिंगलटन का उपयोग करना सबसे अच्छा होगा या यह आगे बढ़ने और इन में मेरी रजिस्ट्री का उपयोग करने के लिए समान होगा?

मुझे अच्छी तरह से पता नहीं है कि ऑब्जेक्ट्स PHP में कैसे काम करते हैं यह जानने के लिए कि किसी भी तरह का प्रदर्शन लाभ (कम स्मृति उपयोग, सीपीयू उपयोग, लोड समय) होगा।

तो इस में अनुभव वाला कोई भी व्यक्ति मुझे बता सकता है कि क्या एक या दूसरे का उपयोग करके कोई लाभ होगा, मैं मंच पर हूं जहां मैं उत्पादन समय या कुछ भी प्रभावित किए बिना ईथर मार्ग जा सकता हूं। अगर मैं अब कर सकता हूं तो मैं सबसे अच्छी विधि का उपयोग करना चाहता हूं।

+0

मैं वास्तव में एक सवाल अभी है कि मूल रूप से एक ही है पाया http://stackoverflow.com/questions/1967363/registry-or-singleton – JasonDavis

+0

आप PHP4 या PHP5 उपयोग कर रहे हैं नोट लें ... वस्तुओं बहुत अलग काम करते हैं, और PHP4 कीवर्ड जैसे 'स्थिर' समर्थित नहीं हैं। संभावना है कि आप 5 का उपयोग कर रहे हैं, लेकिन यदि आप प्रासंगिक ओओपी में जाना चाहते हैं तो आपको यह सुनिश्चित करने की आवश्यकता है। –

उत्तर

3

यह आपके आवेदन पर निर्भर करता है। यदि आपको अभी भी 4 कक्षाओं में से 3 की आवश्यकता है, तो केवल 3 को स्वतंत्र रूप से संभालने के बजाय रजिस्ट्री का उपयोग करना अधिक आदर्श होगा क्योंकि आपको चौथे की आवश्यकता नहीं है। कक्षाओं को लोड करना स्मृति पदचिह्न को कम करने के लिए एक दृष्टिकोण होगा, लेकिन फिर ऑब्जेक्ट बनाने के लिए आपको रजिस्ट्री को निर्देश देना होगा और यह सिंगलेट को संभालने से कहीं अलग नहीं है। वैकल्पिक रूप से, आप एक एन-पैरामीटर कन्स्ट्रक्टर बना सकते हैं या अपनी रजिस्ट्री को निर्देशित करने के लिए एक सरणी का उपयोग कर सकते हैं जो निर्माण के दौरान तत्काल कक्षाएं।

class Registry { 
    public $class1; 
    public $class2; 

    function __construct($uses) { 
     foreach($uses as $class) { 
      $this->{$class} = new {$class}(); 
     } 
    } 

} 

फिर कौन से वर्गों को तत्काल करने के लिए निर्दिष्ट करके अपनी रजिस्ट्री को तुरंत चालू करें।

$reg = new Registry(array('class1')); 

आप स्पष्ट रूप से अपने कन्स्ट्रक्टर को डिफ़ॉल्ट रूप से सभी कक्षाओं को तुरंत चालू करने के लिए शून्य पैरामीटर को संभालने के लिए चाहते हैं।

+0

एक अच्छा विचार है, धन्यवाद। मुझे जिक्र करना चाहिए, भले ही 1 वर्ग को केवल 1-2 वस्तुओं की आवश्यकता हो, फिर भी उसी पृष्ठ पर पहले से ही एक और वर्ग कहा जा रहा है, जिसमें संभवतः सभी 4 ऑब्जेक्ट्स पहले से इंजेक्शन दिए जाएंगे। मुझे यकीन नहीं है कि मेमोरी सामान कैसे काम करता है, इसलिए यह पहले से ही 1 बार लोड हो सकता है। मुझे नहीं पता कि मेमोरी वस्तुओं को एक बार रैम में रखेगी या नहीं। – JasonDavis

+0

मेरा कोड उदाहरण आपके वर्गों को आपके रजिस्ट्री के अपने उदाहरण पर रखता है। यदि आपके पास एक ही सामान्य रजिस्ट्री ऑब्जेक्ट्स का उपयोग करते हुए प्रति पृष्ठ एक से अधिक कक्षाएं हैं, तो इसका बहुत अधिक स्मृति होगा। यदि आप एक स्थिर/वैश्विक उदाहरण का उपयोग कर रहे हैं, तो आपका कार्यान्वयन मेरे उदाहरण से अलग होगा लेकिन यह अभी भी किया जा सकता है। इसका मतलब यह भी होगा कि सभी वर्गों में स्मृति में समान वस्तुओं को साझा करना, जो अधिक कुशल होगा। इस तरह से काम करने के लिए मेरा उदाहरण प्राप्त करने के लिए, कन्स्ट्रक्टर का उपयोग करने के बजाय रजिस्ट्री :: initInstances() फ़ंक्शन बनाएं। –

+0

ठीक है कि मैं क्या सोच रहा था, अनुमान लगाओ कि हम उसी पृष्ठ पर हैं, जैसे कि नीचे dbemerlin से विधि की तरह। – JasonDavis

4

आप आलसी लोड हो रहा है लागू कर सकते हैं केवल वस्तुओं तुम सच में की जरूरत है लोड करने के लिए:

class Registry 
{ 
    private static $database = null; 

    private static function connectDatabase($key) 
    { 
     [... do connection stuff ...] 
    } 

    public static function getDatabase($key) 
    { 
     if (Registry::$database == null) 
     { 
      Registry::connectDatabase($key); 
     } 
     return Registry::$database; 
    } 
} 

डेटाबेस कनेक्शन पैरामीटर रजिस्टर करने के लिए कोड पाठक के लिए व्यायाम के रूप में छोड़ दिया है।

+3

क्या यह सिर्फ एक सिंगलटन नहीं है? – JasonDavis

+0

मुझे नहीं पता कि सिंगलटन –

+0

कहलाया जा सकता है यह शुद्ध सिंगलटन पैटर्न है, जो वास्तव में पैटर्न नहीं है, बल्कि विरोधी पैटर्न है। –

1

शायद यह उचित सिंगलटन-रजिस्ट्री पैटर्न है। ओएफसी, आप विभिन्न चीजों को लागू कर सकते हैं, SplFixedArray, ArrayAccess इंटरफ़ेस, और अन्य। इसके अलावा किसी भी रिसाव को सुनिश्चित करने के लिए आंतरिक वस्तुओं को नष्ट करना और नष्ट करना बुरा नहीं है।

class oRegistry{ 
    private static $instance = null; 

    private $storage = array(); 

    private function __construct(){} 

    private function __clone(){} 

    public static function getInstance(){ 
     if(self::$instance === null){ 
     self::$instance = new self(); 
     } 
     return self::$instance; 
    } 

    public function attach($name, $o) { 
     if(true === isset($this->storage[$name])) { 
      throw new Exception('The instance with name '.$name.' already exists in registry.'); 
     } 
     if(!empty($name)) { 
      $this->storage[ $name ] = $o; 
     } 
    } 

    public function detach($name){ 
     if(isset($this->storage[ $name ])) { 
      $this->storage[ $name ] = null; 
      unset($this->storage[ $name ]); 
     } 
    } 

    public function get($name){ 
     if(false === isset($this->storage[$name])) { 
      throw new Exception('Invalid instance requested'); 
     } 
     return $this->storage[ $name ]; 
    } 
} 

// usage example 
$storage = oRegistry::getInstance(); 
$obj = new stdClass; 
$obj2 = new stdClass; 
$obj->test1 = 'test'; 
$obj2->test2 = 't2'; 

$storage->attach('test1', $obj); 
$storage->attach('test2', $obj2); 

$got = $storage->get('test2'); 
var_dump($got); // object(stdClass)#3 (1) { ["test2"]=> string(2) "t2" } 

$storage->detach('test2'); 
$got = $storage->get('test2'); 
var_dump($got); // bool(false) 
संबंधित मुद्दे