2013-06-10 7 views
5

मुझे PHP विरासत के साथ कुछ परेशानी हो रही है।PHP सिंगलेट्स और विरासत

मैं इस आधार वर्ग है, सिंगलटन:

namespace My_Namespace; 

abstract class Singleton { 
    protected static $instance = null; 

    static function get() { 
     if (null == static::$instance) { 
      static::$instance = new static; 
     } 
     return static::$instance; 
    } 

    private function __construct() { 

    } 
} 

मैं इनहेरिट कि सिंगलटन वर्ग वर्गों का एक समूह है, उन्हें एक फोन बी, सी, डी यहाँ सौदा है। उनमें से एक इस तरह दिखता है:

namespace My_Namespace; 

class A extends Singleton { 

    protected function __construct() { 

     B::get(); 

     if (some_condition()) { 
      C::get(); 
     } 
     else { 
      D::get(); 
     } 
    } 
} 

अब, मैं सिर्फ एक A::get() करना यह सब रोलिंग मिलता है। ए के कन्स्ट्रक्टर को उम्मीद के रूप में बुलाया जाता है। फिर, बी के निर्माता को बिना किसी समस्या के बुलाया जाता है। अब यह अजीब हो जाता है। एक बार C::get() कहा जाता है, यह static::$instance को पहले से ही कक्षा बी की एक वस्तु के रूप में पहचानता है और सी को तुरंत चालू नहीं करता है। मुझे पता है कि अगर मैं उन्हें डेज़ी-चेन देता हूं, तो __construct बी बी C::get या D::get पर काम करता है लेकिन यह मेरे उद्देश्यों के लिए अनुकूल नहीं है। क्या उनके कारण एक ही दायरे में है? यदि हां, तो क्या इसके आसपास कोई रास्ता है? मैं व्यावहारिक उद्देश्य के बजाय जिज्ञासा से अधिक पूछ रहा हूं - मुझे पता है कि मैं उनमें से प्रत्येक में सिंगलटन पैटर्न को आसानी से कार्यान्वित कर सकता हूं। तो, कोई विचार? धन्यवाद!

पीएस कृपया कोई भी 'सिंगलटन बुरा नहीं है और आपको नरक में जला देना चाहिए' टिप्पणियां। मुझे पता है कि पूरी तरह से अच्छी तरह से।

+1

+1 के लिए +1 'नरक टिप्पणियों में जला' – phpisuber01

+1

मेरा मानना ​​है कि उत्तराधिकारी वर्गों को उदाहरण के लिए एक स्थैतिक संपत्ति की आवश्यकता होती है ... इसलिए 'संरक्षित स्थैतिक $ instance = null;' subclasses में जोड़ें । – Orangepill

+0

@ ओरंगपिल आपको मिल गया। मैंने उस पंक्ति को जोड़ा और यह सब अपेक्षित के रूप में काम करता है। 'लेकिन:' उस तरह से पूरे सिंगलटन वर्ग और विरासत की सामग्री बेकार है ... विचार था कि उस वर्ग में सिंगलटन कार्यक्षमता संलग्न है। क्या यह बिल्कुल संभव है? –

उत्तर

2

ध्यान दें कि static::$instance = new static आपके मामले में (A) के निर्माता को कॉल करता है।

आपके समाधान के साथ, आपको अपने सबक्लास में अपने उदाहरण के लिए एक स्थिर संपत्ति की आवश्यकता होगी।

बस उन्हें

protected static $instance = null; 

जोड़ने के लिए, और यह ठीक काम करना चाहिए।

+0

यह पहले दो बार क्यों काम करता है? अगर मैं एक ही दायरे में नहीं हूं, तो 'ए :: get() 'और' B :: get()' में यह उचित उदाहरण बनाता है लेकिन जैसे ही यह 'सी :: get() 'हिट करता है, यह' बी :: get' 'के लिए उपयोग किया जाता है? क्या यह कोई समझ में आता है? –

+1

यह पहले दो बार काम नहीं करता है, यह काम करता है पहली बार। आप 'ए :: get() 'पर कॉल करते हैं। फिर' ए 'के कन्स्ट्रक्टर को कॉल किया जाता है। यह' बेस :: से '$ example' से' बी :: get() 'कहता है * * सेट है (पहली बार यह सेट है)। और अब आप 'सी :: get() 'को कॉल करना चाहते हैं, जो' null == static :: $ instance' की जांच करता है, लेकिन अब '$ instance' ** (कक्षा ए से) ** पहले से ही एक वस्तु है। – bpoiss

+0

मुझे यह जानने के लिए थोड़ी देर लग गई कि स्पष्टीकरण कितना आसान है। उस 'स्थिर :: $ instance = new static' पर, कन्स्ट्रक्टर को कॉल किया जाता है जिसे वास्तविक $ इंस्टेंस वैरिएबल के लिए कुछ भी निर्दिष्ट करने से पहले एक और कन्स्ट्रक्टर कहते हैं, क्योंकि यह अभी तक वापस नहीं आया है। मुझे मूर्ख। जवाब के लिए धन्यवाद। –

1

जब स्थिर गुणों के साथ काम करता है, तो आप विरासत में मिला वर्गों के स्थिर गुणों आधार वर्ग आप एक घर उपलब्ध कराने के लिए यह में रहने के लिए है से अलग करना चाहते हैं।

समस्या को हल करने के लिए बस को परिभाषित

protected static $instance = null; 
आपके व्युत्पन्न वर्ग पर

। यदि नहीं, तो यह बेस क्लास की संपत्ति का उपयोग करेगा।

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