क्या PHP में डेटाबेस एक्सेस के साथ एकल के लिए उपयोग-मामला है?


138

मैं अपने MySQL डेटाबेस को PDO के माध्यम से एक्सेस करता हूं। मैं डेटाबेस तक पहुंच स्थापित कर रहा हूं, और मेरा पहला प्रयास निम्नलिखित का उपयोग करना था:

पहली चीज जो मैंने सोची global:

$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'root', 'pwd');

function some_function() {
    global $db;
    $db->query('...');
}

यह एक बुरा अभ्यास माना जाता है। थोड़ी खोज के बाद, मैंने सिंगलटन पैटर्न के साथ समाप्त किया , जो कि

"उन स्थितियों पर लागू होता है जिनमें किसी वर्ग का एकल उदाहरण होना चाहिए।"

मैनुअल में उदाहरण के अनुसार, हमें यह करना चाहिए:

class Database {
    private static $instance, $db;

    private function __construct(){}

    static function singleton() {
        if(!isset(self::$instance))
            self::$instance = new __CLASS__;

        return self:$instance;
    }

    function get() {
        if(!isset(self::$db))
            self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd')

        return self::$db;
    }
}

function some_function() {
    $db = Database::singleton();
    $db->get()->query('...');
}

some_function();

जब मैं ऐसा कर सकता हूं तो मुझे उस अपेक्षाकृत बड़े वर्ग की आवश्यकता क्यों है?

class Database {
    private static $db;

    private function __construct(){}

    static function get() {
        if(!isset(self::$db))
            self::$db = new PDO('mysql:host=127.0.0.1;dbname=toto', 'user', 'pwd');

        return self::$db;
    }
}

function some_function() {
    Database::get()->query('...');
}

some_function();

यह पिछले एक पूरी तरह से काम करता है और मुझे $dbअब और चिंता करने की आवश्यकता नहीं है।

मैं एक छोटा सिंगलटन वर्ग कैसे बना सकता हूं, या क्या ऐसे एकल-उपयोग का मामला है जो मैं PHP में याद कर रहा हूं?


इस संबंधित प्रश्न में बहुत सारे संसाधन और चर्चा है: 'एकल गायकों के बारे में इतना बुरा क्या है?'
फ्रूटब्रेक

जवाबों:


80

ठीक है, मैं कुछ समय के लिए आश्चर्यचकित हो गया जब मैंने पहली बार अपना करियर शुरू किया। इसे अलग-अलग तरीकों से लागू किया और दो कारणों के साथ आया कि वे स्थिर वर्गों का उपयोग न करें, लेकिन वे बहुत बड़े हैं।

एक यह है कि आप पाएंगे कि बहुत बार कुछ ऐसा होता है जो आपको पूरी तरह से यकीन है कि आपके पास कभी भी एक से अधिक उदाहरण नहीं होंगे, आपके पास अंततः एक दूसरा है। आप एक दूसरे मॉनिटर, एक दूसरे डेटाबेस, एक दूसरे सर्वर - जो भी हो, के साथ समाप्त हो सकते हैं।

जब ऐसा होता है, यदि आपने एक स्थिर वर्ग का उपयोग किया है तो आप बहुत खराब रिफ्लेक्टर की तुलना में हैं यदि आपने एक सिंगलटन का उपयोग किया है। एक सिंगलटन अपने आप में एक iffy पैटर्न है, लेकिन यह काफी आसानी से एक बुद्धिमान कारखाने के पैटर्न में परिवर्तित हो जाता है - यहां तक ​​कि बहुत अधिक परेशानी के बिना निर्भरता इंजेक्शन का उपयोग करने के लिए परिवर्तित किया जा सकता है। उदाहरण के लिए, यदि आपका सिंगलटन getInstance () के माध्यम से प्राप्त किया जाता है, तो आप बहुत आसानी से उस getInstance (databaseName) को बदल सकते हैं और कई डेटाबेस के लिए अनुमति दे सकते हैं - कोई अन्य कोड परिवर्तन नहीं।

दूसरा मुद्दा परीक्षण है (और ईमानदारी से, यह पहले अंक के समान ही है)। कभी-कभी आप अपने डेटाबेस को एक नकली डेटाबेस से बदलना चाहते हैं। वास्तव में यह डेटाबेस ऑब्जेक्ट का दूसरा उदाहरण है। यह स्थिर वर्गों के साथ करने के लिए बहुत कठिन है, क्योंकि यह एक सिंगलटन के साथ है, आपको केवल getInstance () विधि का मजाक उड़ाना होगा, न कि प्रत्येक एकल विधि एक स्थिर कक्षा में (जो कुछ भाषाओं में बहुत कठिन हो सकती है)।

यह वास्तव में आदतों के लिए नीचे आता है - और जब लोग कहते हैं कि "ग्लोबल्स" खराब हैं, तो उनके पास ऐसा कहने के लिए बहुत अच्छे कारण हैं, लेकिन यह हमेशा स्पष्ट नहीं हो सकता है जब तक कि आप समस्या को स्वयं हिट नहीं करते हैं।

सबसे अच्छी बात यह है कि आप पूछ सकते हैं (जैसे आपने किया) फिर एक विकल्प बनाएं और अपने निर्णय के प्रभावों का निरीक्षण करें। समय के साथ अपने कोड के विकास की व्याख्या करने के लिए ज्ञान होना पहली बार में सही करने से कहीं अधिक महत्वपूर्ण है।


15
आप कहते हैं कि सिंग्लेटन्स डीआई के लिए अच्छी तरह से अवहेलना करते हैं, लेकिन क्या आपके उदाहरण getInstance(databaseName)अभी भी आपके कोड में वैश्विक उदाहरणों के भंडार का संदर्भ नहीं दे रहे हैं? जिस कोड को कॉल किया getInstanceजाना चाहिए, उसके पास ग्राहक कोड द्वारा इंजेक्ट किया गया उदाहरण होना चाहिए, और इसलिए getInstanceउसे पहली जगह पर कॉल करने की आवश्यकता नहीं होनी चाहिए ।
विलसन

1
@Will Vousden Correct, यह एक तरह का स्टॉप-गैप है। यह वास्तव में DI नहीं है, लेकिन यह बहुत करीब हो सकता है। उदाहरण के लिए, अगर यह getInstance (SupportDatabase) हो और वापस लौटा गया हो तो किस डेटाबेस के आधार पर गणना की गई थी? बिंदु यह है कि जब तक वे इसके लिए तैयार न हों तब तक डीआई ढांचे वाले लोगों को डराने से बचें।
बिल के

320

Singletons बहुत कम है - अगर नहीं कहने के लिए - PHP में उपयोग करें।

उन भाषाओं में जहां ऑब्जेक्ट्स साझा मेमोरी में रहते हैं, सिंगलेटन का उपयोग मेमोरी उपयोग को कम रखने के लिए किया जा सकता है। दो ऑब्जेक्ट बनाने के बजाय, आप विश्व स्तर पर साझा एप्लिकेशन मेमोरी से मौजूदा उदाहरण का संदर्भ देते हैं। PHP में ऐसी कोई एप्लीकेशन मेमोरी नहीं है। एक अनुरोध में बनाया गया एक सिंगलटन उस अनुरोध के लिए वास्तव में रहता है। एक ही समय में किए गए एक अन्य अनुरोध में बनाया गया एक सिंगलटन अभी भी पूरी तरह से अलग उदाहरण है। इस प्रकार, एक सिंगलटन के दो मुख्य उद्देश्यों में से एक यहां लागू नहीं है।

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

अन्य उद्देश्य के लिए एक ही अनुरोध के भीतर एक उदाहरण के लिए एक वैश्विक पहुँच बिंदु होगा। हालांकि यह वांछनीय लग सकता है, यह वास्तव में isnt नहीं है, क्योंकि यह वैश्विक दायरे (जैसे किसी ग्लोबल्स और स्टेटिक्स) के लिए युग्मन बनाता है। यह यूनिट-परीक्षण को कठिन बनाता है और आपके आवेदन को सामान्य रूप से कम बनाए रखता है। इसे कम करने के तरीके हैं, लेकिन सामान्य तौर पर, यदि आपको कई वर्गों में एक ही उदाहरण की आवश्यकता है, तो निर्भरता इंजेक्शन का उपयोग करें ।

PHP में Singletons के लिए मेरी स्लाइड देखें - वे क्यों खराब हैं और आप अतिरिक्त जानकारी के लिए उन्हें अपने अनुप्रयोगों से कैसे समाप्त कर सकते हैं।

यहां तक ​​कि एरिक गामा , जो सिंगलटन पैटर्न के आविष्कारकों में से एक है, आजकल इस पैटर्न पर संदेह करता है:

"मैं सिंगलटन को छोड़ने के पक्ष में हूं। इसका उपयोग लगभग हमेशा एक डिजाइन गंध है"

आगे की पढाई

यदि, उपरोक्त के बाद, आपको अभी भी निर्णय लेने में मदद चाहिए:

सिंगलटन निर्णय आरेख


1
@ बोर्डन हां। और भले ही अनुरोधों के बीच वस्तुओं को बनाए रखना संभव था, फिर भी सिंग्लेटन्स ने कुछ ठोस सिद्धांतों का उल्लंघन किया और ग्लोबल स्टेट को पेश किया।
गॉर्डन

4
प्रवाह के खिलाफ जाने के लिए क्षमा करें, लेकिन DI वास्तव में उस समस्या का हल नहीं है, जिसके लिए सिंगलटन का उपयोग किया जा रहा है, जब तक कि आप 42 ctor पैरामीटर (या 42 setFoo) (और setBar) () कॉल के साथ कक्षाएं नहीं ले रहे हैं, इसे बनाने के लिए आवश्यक है काम)। हां, कुछ ऐप्स, दुर्भाग्यवश, इस कपल को होना चाहिए और बहुत सी बाहरी चीजों पर निर्भर होना चाहिए। PHP एक ग्लू भाषा है, और कभी-कभी एक साथ गोंद करने के लिए बहुत सी चीजें होती हैं।
स्टैसम

14
@StasM यदि आप 42 ctor params कर रहे हैं या आपको बहुत सारे बसने की आवश्यकता है तो आप इसे गलत कर रहे हैं। कृपया स्वच्छ कोड वार्ता देखें। क्षमा करें, अगर मुझे यह समझाने के लिए परेशान नहीं किया जा सकता है कि यह एक और समय है। अधिक जानकारी के लिए PHP चैटरूम में बेझिझक पूछें।
गॉर्डन

@Gordon php चैट रूम कहाँ है?
user658182

21

PHP में सिंगलेट्स की आवश्यकता किसे है?

ध्यान दें कि एकल के लगभग सभी आपत्तियां तकनीकी दृष्टिकोण से आती हैं - लेकिन वे भी अपने दायरे में सीमित हैं। खासकर PHP के लिए। सबसे पहले, मैं सिंग्लेटन्स का उपयोग करने के कुछ कारणों की सूची दूंगा, और फिर मैं सिंग्नलों के उपयोग की आपत्तियों का विश्लेषण करूंगा। सबसे पहले, जिन लोगों को उनकी आवश्यकता है:

- जो लोग एक बड़े ढांचे / कोडबेस को कोड कर रहे हैं, जो कई अलग-अलग वातावरणों में उपयोग किए जाएंगे, उन्हें पहले से मौजूद, अलग-अलग फ्रेमवर्क / कोडबेस के साथ काम करना होगा, कई अलग-अलग, बदलते, यहां तक ​​कि ग्राहकों और मालिकों के लिए अनुरोधों को लागू करने की आवश्यकता के साथ। / प्रबंधन / इकाई नेता करते हैं।

देखें, सिंगलटन पैटर्न स्वयं समावेशी है। जब किया जाता है, तो एक एकल वर्ग आपके द्वारा शामिल किए गए किसी भी कोड में कठोर होता है, और यह ठीक उसी तरह कार्य करता है जैसे आपने इसके तरीके और चर कैसे बनाए। और किसी दिए गए अनुरोध में हमेशा एक ही वस्तु होती है। चूंकि यह दो अलग-अलग वस्तुओं के लिए दो बार नहीं बनाया जा सकता है, आप जानते हैं कि एक कोड में किसी भी बिंदु पर एक सिंगलटन ऑब्जेक्ट क्या है - भले ही सिंगलटन को दो, तीन अलग-अलग, पुराने, यहां तक ​​कि स्पेगेटी कोडबेस में डाला जाए। इसलिए, यह विकास के उद्देश्यों के संदर्भ में आसान बनाता है - भले ही उस परियोजना में कई लोग काम कर रहे हों, जब आप किसी सिंगलबेल को किसी भी कोडबेस में एक बिंदु पर आरंभीकृत होते हुए देखते हैं, तो आप जानते हैं कि यह क्या है, यह क्या करता है, यह कैसे होता है करता है, और यह जिस राज्य में है। यदि यह पारंपरिक वर्ग था, तो आपको उस वस्तु का ट्रैक रखने की आवश्यकता होगी जो पहली बार बनाई गई थी। कोड में उस बिंदु तक, और इसकी विशेष स्थिति तक इसमें कौन से तरीके लागू किए गए थे। लेकिन, एक सिंगलटन को वहीं छोड़ दें, और यदि आपने उचित डिबगिंग और सूचना विधियों को छोड़ दिया और इसे कोडिंग करते समय सिंगलटन में ट्रैकिंग करते हैं, तो आप वास्तव में जानते हैं कि यह क्या है। इसलिए, यह उन लोगों के लिए आसान बनाता है जिन्हें अलग-अलग कोडबेस के साथ काम करना पड़ता है, कोड को एकीकृत करने की आवश्यकता के साथ जो पहले अलग-अलग दर्शन के साथ किया गया था, या उन लोगों द्वारा किया गया जिनके साथ आपका कोई संपर्क नहीं है। (यह है, विक्रेता-परियोजना-कंपनी-जो कुछ भी नहीं है, कोई समर्थन नहीं है)। यह उन लोगों के लिए आसान बनाता है जिन्हें अलग-अलग कोडबेस के साथ काम करना पड़ता है, कोड को एकीकृत करने की आवश्यकता के साथ जो पहले अलग-अलग दर्शन के साथ किया गया था, या उन लोगों द्वारा किया गया, जिनके साथ आपका कोई संपर्क नहीं है। (यह है, विक्रेता-परियोजना-कंपनी-जो कुछ भी नहीं है, कोई समर्थन नहीं है)। यह उन लोगों के लिए आसान बनाता है जिन्हें अलग-अलग कोडबेस के साथ काम करना पड़ता है, कोड को एकीकृत करने की आवश्यकता के साथ जो पहले अलग-अलग दर्शन के साथ किया गया था, या उन लोगों द्वारा किया गया, जिनके साथ आपका कोई संपर्क नहीं है। (यह है, विक्रेता-परियोजना-कंपनी-जो कुछ भी नहीं है, कोई समर्थन नहीं है)।

- जिन लोगों को तीसरे पक्ष के एपीआई , सेवाओं और वेबसाइटों के साथ काम करने की आवश्यकता है ।

यदि आप करीब से देखते हैं, तो यह पहले के मामले से बहुत अलग नहीं है - थर्ड-पार्टी एपीआई, सेवाएं, वेबसाइट, केवल बाहरी, पृथक कोडबेस की तरह हैं, जिन पर आपका कोई नियंत्रण नहीं है। कुछ भी हो सकता है। इसलिए, एक सिंगलटन सत्र / उपयोगकर्ता वर्ग के साथ, आप किसी भी प्रकार के सत्र / प्राधिकरण कार्यान्वयन का प्रबंधन कर सकते हैं, जैसे कि OpenID , फेसबुक , ट्विटर और कई और अधिक - और आप SAME सिंगलटन ऑब्जेक्ट से एक ही समय में ये सभी कर सकते हैं - जो किसी भी कोड में किसी भी बिंदु पर एक ज्ञात स्थिति में, जो आप इसे प्लग इन करते हैं, आसानी से सुलभ है। आप अपनी स्वयं की वेबसाइट / एप्लिकेशन में SAME उपयोगकर्ता के लिए कई अलग-अलग, तृतीय-पक्ष API / सेवाओं के लिए कई सत्र बना सकते हैं और जो कुछ भी आप उनके साथ करना चाहते हैं वह कर सकते हैं।

बेशक, यह सब सामान्य वर्गों और वस्तुओं का उपयोग करके पारंपरिक तरीकों के साथ भी टोन किया जा सकता है - यहां पकड़ है, सिंगलटन टिडियर, नटर है और इसलिए इस तरह की स्थितियों में पारंपरिक वर्ग / वस्तु के उपयोग की तुलना में उस प्रबंधनीय / परीक्षण योग्य आसान के कारण।

- जिन लोगों को तेजी से विकास करने की आवश्यकता है

एकल के वैश्विक प्रकार के व्यवहार से फ्रेमवर्क के साथ किसी भी प्रकार का कोड बनाना आसान हो जाता है जिसमें निर्माण करने के लिए एकल के संग्रह होते हैं, क्योंकि एक बार जब आप अपने एकल वर्ग का अच्छी तरह से निर्माण करते हैं, तो स्थापित, परिपक्व और सेट विधियां आसानी से उपलब्ध होंगी और कहीं भी प्रयोग करने योग्य, कभी भी, एक सुसंगत फैशन में। आपकी कक्षाओं को परिपक्व करने में कुछ समय लगता है, लेकिन उसके बाद, वे ठोस और सुसंगत, और उपयोगी होते हैं। आप एक सिंगलटन में कई तरीके अपना सकते हैं, जो आप चाहते हैं, और हालांकि, यह ऑब्जेक्ट की मेमोरी फ़ुटप्रिंट को बढ़ा सकता है, यह तेजी से विकास के लिए आवश्यक समय में बहुत अधिक बचत लाता है - एक विधि जिसे आप किसी दिए गए उदाहरण में उपयोग नहीं कर रहे हैं एक एप्लिकेशन को किसी अन्य एकीकृत में उपयोग किया जा सकता है, और आप बस एक नई सुविधा को थप्पड़ मार सकते हैं जिसे क्लाइंट / बॉस / प्रोजेक्ट मैनेजर केवल कुछ संशोधनों द्वारा पूछता है।

तुम्हें नया तरीका मिल गया है। अब एकल के आपत्तियों और अपवित्र धर्मयुद्ध पर आपत्ति जताते हैं, जो उपयोगी है :

- सबसे बड़ी आपत्ति यह है कि यह कठिन परीक्षण करता है।

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

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

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

लेकिन उन लोगों के लिए जिन्हें 'फुर्तीली' विकास की गंदी खाई में काम करने की ज़रूरत है, अपने ग्राहक / प्रबंधक / परियोजना से कई अलग-अलग अनुरोधों (कभी-कभी अनुचित) को लागू करने के लिए, पहले बताए गए कारणों के कारण सिंगलटन एक बचत अनुग्रह है।

- एक और आपत्ति यह है कि इसकी मेमोरी फुटप्रिंट अधिक है

क्योंकि प्रत्येक ग्राहक से प्रत्येक अनुरोध के लिए एक नया सिंगलटन मौजूद होगा, यह MAY PHP के लिए एक आपत्ति है। बुरी तरह से निर्मित और उपयोग किए गए एकल के साथ, किसी एप्लिकेशन के मेमोरी फ़ुटप्रिंट अधिक हो सकते हैं यदि कई उपयोगकर्ताओं को किसी भी बिंदु पर एप्लिकेशन द्वारा सेवा दी जाती है।

हालांकि, यह किसी भी तरह के दृष्टिकोण के लिए मान्य है जो आप चीजों को कोड करते समय ले सकते हैं। जो प्रश्न पूछे जाने चाहिए, क्या वे तरीके हैं, डेटा जो इन सिंगलेटों द्वारा आयोजित और संसाधित किए जाते हैं अनावश्यक हैं? यदि वे अनुरोधों में से कई के लिए आवश्यक हैं, तो आवेदन प्राप्त कर रहे हैं, भले ही आप एकल, उन विधियों और डेटा का उपयोग न करें, जो आपके आवेदन में किसी न किसी रूप में कोड के माध्यम से मौजूद होंगे। तो, यह सब एक सवाल बन जाता है कि जब आप किसी पारंपरिक क्लास ऑब्जेक्ट 1/3 को कोड प्रोसेसिंग में इनिशियलाइज़ करते हैं, तो आप कितनी मेमोरी सेव कर रहे होंगे, और उसमें 3/4 को नष्ट कर देंगे।

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

- कुछ अवैध आपत्तियाँ जैसे 'कई डेटाबेस को बनाए रखना असंभव / कठिन बना देता है'

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

नीचे दी गई कल्पना कीजिए कि किसी दिए गए डेटाबेस सिंगलटन के अंदर:

$ यह -> कनेक्शन = सरणी (); (गलत सिंटैक्स, मैंने आपको चित्र देने के लिए इसे इस तरह टाइप किया - चर की उचित घोषणा सार्वजनिक $ कनेक्शन = सरणी () है, और इसका उपयोग $ यह है-> कनेक्शन ['कनेक्शन'] स्वाभाविक रूप से)

आप सेट अप कर सकते हैं, और किसी भी समय इस शैली में एक सरणी में कई कनेक्शन रख सकते हैं। और उसी के लिए प्रश्न, परिणाम सेट और आगे जाते हैं।

$ यह -> क्वेरी (QUERYSTRING, 'queryname', $ this-> कनेक्शन ['particulrconnection]]);

जो चयनित कनेक्शन के साथ एक चयनित डेटाबेस के लिए एक क्वेरी कर सकता है, और बस आपके स्टोर में स्टोर कर सकता है

$ यह -> परिणाम

प्रमुख 'क्वेरीनाम' के साथ सरणी। बेशक, आपको इसके लिए अपनी क्वेरी विधि कोडित करनी होगी - जो करने के लिए तुच्छ है।

यह आपको डेटाबेस की लगभग अनंत संख्या (जितना संसाधन सीमा की अनुमति देता है) को बनाए रखने में सक्षम बनाता है, उतना ही अलग-अलग डेटाबेस कनेक्शन और परिणाम सेट करता है जितना आपको उनकी आवश्यकता है। और वे किसी भी दिए गए कोडबेस में किसी भी बिंदु पर कोड के किसी भी टुकड़े के लिए उपलब्ध हैं, जिसमें इस एकल वर्ग को त्वरित किया गया है।

बेशक, आपको स्वाभाविक रूप से परिणाम सेट, और कनेक्शन की ज़रूरत पड़ने पर मुक्त करना होगा - लेकिन यह बिना कहे चला जाता है, और यह एकल या किसी अन्य कोडिंग पद्धति / शैली / अवधारणा के लिए विशिष्ट नहीं है।

इस बिंदु पर, आप देख सकते हैं कि आप एक ही सिंगलटन में तीसरे पक्ष के अनुप्रयोगों या सेवाओं के लिए कई कनेक्शन / राज्यों को कैसे बनाए रख सकते हैं। इतना अलग नहीं है।

लंबी कहानी छोटी, अंत में, सिंगलटन पैटर्न केवल एक अन्य विधि / शैली / दर्शन है जिसके साथ प्रोग्राम करना है, और वे किसी भी अन्य के रूप में उपयोगी हैं जब वे सही जगह पर, सही फैशन में उपयोग किए जाते हैं। जो किसी चीज से अलग न हो।

आप देखेंगे कि अधिकांश लेखों में, जिनमें एकल गीतों को धराशायी किया गया है, आपको 'ग्लोबल्स' के 'दुष्ट' होने के संदर्भ में भी देखा जाएगा।

आइए इसका सामना करें - कुछ भी जो ठीक से उपयोग नहीं किया जाता है, दुर्व्यवहार, दुरुपयोग, आईएस बुराई है। यह किसी भी भाषा, किसी भी कोडिंग अवधारणा, किसी भी विधि तक सीमित नहीं है। जब भी आप किसी को 'एक्स बुराई है' जैसे कंबल बयान जारी करते हुए देखते हैं, तो उस लेख से भाग जाते हैं। संभावना बहुत अधिक है कि यह एक सीमित दृष्टिकोण का उत्पाद है - भले ही दृष्टिकोण किसी विशेष चीज में वर्षों के अनुभव का परिणाम है - जो आम तौर पर किसी दिए गए शैली / पद्धति में बहुत अधिक काम करने का परिणाम है - ठेठ बौद्धिक रूढ़िवाद।

इसके लिए अंतहीन उदाहरण दिए जा सकते हैं, जिनमें 'ग्लोबल्स इज़ एविल' से लेकर 'इफ्रेम्स इज़ दुष्ट' हैं। लगभग 10 साल पहले, यहां तक ​​कि किसी भी आवेदन में एक iframe के उपयोग का प्रस्ताव भी विधर्मी था। फिर फेसबुक आता है, हर जगह इफ्रेम्स, और देखो क्या हुआ है - इफ्रेम्स इतने बुरे नहीं हैं।

अभी भी ऐसे लोग हैं जो ज़िद करते हैं कि वे 'दुष्ट' हैं - और कभी-कभी अच्छे कारण के लिए भी - लेकिन, जैसा कि आप देख सकते हैं, एक ज़रूरत है, iframes उस ज़रूरत को पूरा करते हैं और अच्छी तरह से काम करते हैं, और इसलिए पूरी दुनिया बस चलती है।

एक प्रोग्रामर / कोडर / सॉफ्टवेयर इंजीनियर की सबसे महत्वपूर्ण संपत्ति एक स्वतंत्र, खुला और लचीला दिमाग है।


2
-1। जबकि मैं मानता हूं कि एक खुले और लचीले दिमाग का होना किसी भी डेवलपर के लिए संपत्ति होना चाहिए, यह सिंग्लटन को एंटीपैटर्न होने से नहीं बचाता है। उपर्युक्त उत्तर में प्रकृति और सिंग्लटन के प्रभावों के बारे में इतने गलत कथन और गलत निष्कर्ष शामिल हैं जिन्हें मैं अस्वीकार नहीं कर सकता।
गॉर्डन

-1। मुझे पहले कई सिंगलेट्स के साथ एक रूपरेखा का अनुभव करना पड़ा और स्वचालित परीक्षण असंभव है। मुझे एक ब्राउज़र में परीक्षण और त्रुटि के माध्यम से मैन्युअल रूप से सब कुछ परीक्षण करना होगा। कोड की समीक्षा (वर्तनी, वाक्यविन्यास त्रुटियों) के साथ कुछ त्रुटियां रोकी जा सकती हैं, लेकिन कार्यात्मक त्रुटियां अक्सर छिपी रहती हैं। इस परीक्षण के लिए बहुत अधिक समय की आवश्यकता होती है तब इकाई परीक्षण होता है। इकाई परीक्षणों के साथ मैं कह सकता हूं: यह वर्ग अलगाव में काम करता है, त्रुटि कहीं और होनी चाहिए। बिना डिबगिंग थकाऊ है।
जिम मार्टिन ने

फ्रेमवर्क को लॉगिंग और एरर ट्रैकिंग में बनाया गया था। इसके अलावा, एक वर्ग जो अलगाव में ठीक से काम कर रहा है, एक व्यापक आवेदन में डालते समय एकल रूप में भी ठीक से काम करेगा। जिसका अर्थ है कि उस मामले में जो टूट रहा है वह एक और वर्ग या कार्य होगा जो उस एकल के साथ बातचीत कर रहा है। यह एक बड़े एप्लिकेशन के अंदर साधारण बग ट्रैकिंग से अलग नहीं है। जो कि उचित लॉगिंग वाले एप्लिकेशन के बिना स्वयं काफी कठिन है।
एकता 100

गलत। टन के सिंगलेट्स निश्चित रूप से EVIL हैं, क्योंकि यह परीक्षण-एचईएल बनाता है। :-) हालाँकि, प्रति ऐपल एक सिंगलनेटोन अच्छा हो सकता है। उदाहरण के लिए: एकीकृत लॉगिंग सुविधा के रूप में - सभी एप्लिकेशन (कुछ विरासत-कोड वाले सहित) को लागू करने के लिए।
फ़िलिप ओवर्टोनिंगर रिंगो

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

15

सिंगलेट्स को कई लोगों द्वारा प्रतिमान माना जाता है क्योंकि वे वास्तव में महज वैश्विक चर हैं। अभ्यास में, जहां यह है अपेक्षाकृत कुछ परिदृश्यों देखते हैं आवश्यक एक वर्ग केवल एक उदाहरण के लिए के लिए; आमतौर पर यह सिर्फ इतना है कि एक उदाहरण पर्याप्त है , इस मामले में एक सिंगलटन के रूप में इसे लागू करना पूरी तरह अनावश्यक है।

प्रश्न का उत्तर देने के लिए, आप सही कह रहे हैं कि सिंगलटन यहां ओवरकिल हैं। एक साधारण चर या कार्य करेगा। एक बेहतर (अधिक मजबूत) दृष्टिकोण, हालांकि, वैश्विक चर की आवश्यकता को पूरी तरह से हटाने के लिए निर्भरता इंजेक्शन का उपयोग करना होगा ।


लेकिन सिंगलेट्स डीआई में बहुत आसानी से गिरावट कर सकते हैं, स्थिर वर्ग नहीं कर सकते हैं, जो कि स्थिर वर्गों के साथ वास्तविक समस्या है।
बिल के

@ बिल: बहुत सच है, लेकिन फिर यही कारण है कि मैं एक डीआई दृष्टिकोण की वकालत करना शुरू करूंगा, बजाय इसके कि ढीले कार्य या स्थिर तरीके :)
विल वुडेन

कुछ भाषाओं (जैसे जावा) में स्थिर कक्षाएं (या कक्षाओं के स्थिर तरीके) को बढ़ाया नहीं जा सकता है। तो आप भविष्य के डेवलपर्स के लिए संभावित समस्याएं (या सबसे अच्छा, अधिक काम) बनाते हैं। तो कुछ सुझाव देते हैं कि स्थिर तरीकों से आम तौर पर बचा जाना चाहिए जब तक कि आपको उनके लिए कोई विशिष्ट आवश्यकता न हो।
मार्वो

8

आपके उदाहरण में, आप प्रतीत होता है अपरिवर्तित जानकारी के एक टुकड़े के साथ काम कर रहे हैं। इस उदाहरण के लिए एक सिंगलटन ओवरकिल होगा और एक कक्षा में स्थिर फ़ंक्शन का उपयोग करने से बस ठीक हो जाएगा।

अधिक विचार: आप पैटर्न के लिए पैटर्न लागू करने का एक मामला अनुभव कर रहे हैं और आपका पेट आपको बता रहा है "नहीं, आपको उन कारणों के लिए" नहीं है जो आपने बताए हैं।

लेकिन: हमें आपकी परियोजना के आकार और दायरे का कोई पता नहीं है। यदि यह सरल कोड है, तो संभवत: इसे फेंक दें, फिर इसे बदलने की आवश्यकता नहीं है, हां, आगे बढ़ें और स्थिर सदस्यों का उपयोग करें। लेकिन, अगर आपको लगता है कि आपकी परियोजना को स्केल करने की आवश्यकता हो सकती है या सड़क के नीचे कोडिंग के लिए पहले से तैयार होना चाहिए, तो, हो सकता है कि आप सिंगलटन पैटर्न का उपयोग करना चाहें।


1
वाह, बस सादा गलत। अंतर का पूरा बिंदु (प्रश्न का उत्तर) बाद में दूसरा उदाहरण जोड़ने के लिए अपने कोड को ठीक करना कितना कठिन है। यह करना बहुत कठिन है कि यदि आपने स्थिर विधियों का उपयोग किया है। यह कहने जैसा है कि "ग्लोबल्स आपकी सीमित परिस्थितियों में ठीक हैं" जब ग्लोबल्स के साथ पूरी समस्या यह है कि स्थिति बदल जाती है।
बिल के

@ बिल के: मैं आपसे सहमत हूं और मैं एक सिंगलटन का उपयोग करूंगा यदि कोई जटिलता हो। लेकिन मैं ओपी के दृष्टिकोण से सवाल का जवाब देने की कोशिश कर रहा था और सोचा, ठीक है, हाँ, मुझे लगता है कि यह बहुत सीमित मामले में ओवरकिल है। बेशक मैं वास्तुशिल्प या स्केलेबिलिटी चिंताओं और अन्य विचारों के एक टन की अनदेखी कर रहा था। क्या मुझे अपने उत्तर में एक चेतावनी के साथ यह कहते हुए कि एक व्यक्ति को हमेशा एक सिंगलटन का उपयोग करना चाहिए, जो निश्चित रूप से दूसरों के कारण होता है?
पॉल सासिक

5

सबसे पहले, मैं सिर्फ यह कहना चाहता हूं कि मुझे सिंगलटन पैटर्न का ज्यादा उपयोग नहीं करना है। कोई एक वस्तु को पूरी तरह से पूरी तरह से रखना क्यों चाहेगा? विशेष रूप से डेटाबेस के लिए, क्या होगा यदि मैं किसी अन्य डेटाबेस सर्वर से कनेक्ट करना चाहता हूं? मुझे हर बार डिस्कनेक्ट और पुन: कनेक्ट करना होगा ...? वैसे भी ...

एक अनुप्रयोग में ग्लोबल्स का उपयोग करने के लिए कई कमियां हैं (जो कि सिंगलटन पैटर्न का पारंपरिक उपयोग करता है):

  • यूनिट टेस्ट में मुश्किल
  • निर्भरता इंजेक्शन मुद्दों
  • लॉकिंग समस्याएँ (बहु थ्रेडेड एप्लिकेशन) बना सकते हैं

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

आप पारंपरिक getInstanceपद्धति का उपयोग किए बिना एक वर्ग के उदाहरणों की संख्या को सीमित कर सकते हैं :

class Single {

    static private $_instance = false;

    public function __construct() {
        if (self::$_instance)
           throw new RuntimeException('An instance of '.__CLASS__.' already exists');

        self::$_instance = true;
    }

    private function __clone() {
        throw new RuntimeException('Cannot clone a singleton class');
    }

    public function __destruct() {
        self::$_instance = false;
    }

}

$a = new Single;
$b = new Single; // error
$b = clone($a); // error
unset($a);
$b = new Single; // works

यह ऊपर वर्णित पहले बिंदुओं पर मदद करेगा: यूनिट परीक्षण और निर्भरता इंजेक्शन; यह सुनिश्चित करते हुए कि आपके आवेदन में कक्षा का एक भी उदाहरण मौजूद है। आप उदाहरण के लिए, बस अपने मॉडल (एमवीसी पैटर्न) के परिणामी ऑब्जेक्ट को उनके उपयोग के लिए पास कर सकते हैं।


5

बस इस बात पर विचार करें कि PHP डॉक्स में प्रस्तुत किए गए एक से आपका समाधान कैसे भिन्न होता है। वास्तव में, केवल एक "छोटा" अंतर है: आपका समाधान एक PDOउदाहरण के साथ गेट्टर के कॉलर्स प्रदान करता है , जबकि डॉक्स में Database::singletonसे एक Databaseउदाहरण के साथ कॉलर्स प्रदान करता है (वे तब एक PDOउदाहरण प्राप्त करने के लिए गेट्टर का उपयोग करते हैं )।

तो हम किस निष्कर्ष पर पहुँचे?

  • प्रलेखन कोड में, कॉल करने वालों को एक Databaseउदाहरण मिलता है । Databaseवर्ग बेनकाब कर सकते हैं (वास्तव में, यह चाहिए अगर आप 'सभी इस मुसीबत के लिए जा रहे हैं बेनकाब) की तुलना में एक अमीर या उच्च स्तरीय इंटरफेस PDOवस्तु यह गिर्द घूमती है।
  • यदि आप दूसरे (अमीर) प्रकार से लौटने के लिए अपना कार्यान्वयन बदलते हैं PDO, तो दो कार्यान्वयन समान हैं। मैनुअल कार्यान्वयन के बाद होने का कोई लाभ नहीं है।

व्यावहारिक पक्ष पर, सिंगलटन एक विवादास्पद पैटर्न है। यह मुख्य रूप से है क्योंकि:

  • यह अति प्रयोग है। नौसिखिए प्रोग्रामर सिंगलटन को अन्य पैटर्नों की तुलना में ज्यादा आसान बनाते हैं। वे तब हर जगह अपने नए ज्ञान को लागू करने के लिए जाते हैं, भले ही सिंग्लटन के बिना हाथ में समस्या को बेहतर ढंग से हल किया जा सकता है (जब आप एक हथौड़ा पकड़ रहे हैं, सब कुछ एक नाखून की तरह दिखता है)।
  • प्रोग्रामिंग भाषा पर निर्भर करते हुए, एक एयरटाइट में एक सिंगलटन को लागू करना, गैर-लीक तरीके से एक टाइटैनिक कार्य साबित हो सकता है (विशेषकर यदि हमारे पास उन्नत परिदृश्य हैं: एक सिंगलटन एक और सिंगलटन, सिंगलटन के आधार पर नष्ट हो सकता है और फिर से बनाया जा सकता है, आदि) )। बस C ++ में "निश्चित" सिंगलटन कार्यान्वयन के लिए खोज करने का प्रयास करें, मैंने आपको (मैं आंद्रेई अलेक्जेंड्रेस्कु के आधुनिक सी ++ डिज़ाइन के ग्राउंडब्रेकिंग के मालिक हैं, जो कि गंदगी के बहुत सारे दस्तावेज हैं)।
  • यह सिंगलटन को कोड करते समय और इसे एक्सेस करने के लिए कोड लिखते समय दोनों पर अतिरिक्त कार्यभार लगाता है, कार्यभार जो आप अपने प्रोग्राम वेरिएबल्स के साथ क्या करने की कोशिश करते हैं, उस पर कुछ स्व-लगाए गए अवरोधों का पालन किए बिना कर सकते हैं।

तो, अंतिम निष्कर्ष के रूप में: आपका सिंगलटन ठीक है। सिंगलटन का उपयोग बिल्कुल भी ठीक नहीं है और ज्यादातर समय ठीक है।


2

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


2

जब वहाँ प्रोग्रामिंग "सही" और "गलत" नहीं है; "अच्छा अभ्यास" और "बुरा अभ्यास" है।

सिंगलेट्स को आम तौर पर बाद में पुन: उपयोग किए जाने वाले वर्ग के रूप में बनाया जाता है। उन्हें इस तरह से बनाने की आवश्यकता है कि प्रोग्रामर गलती से दो उदाहरणों को तुरंत नहीं करता है, जबकि आधी रात को शराबी कोडिंग करता है।

यदि आपके पास एक साधारण सा वर्ग है जिसे एक से अधिक बार त्वरित नहीं किया जाना चाहिए , तो आपको इसे एकल बनाने की आवश्यकता नहीं है । यदि आप ऐसा करते हैं तो यह एक सुरक्षा जाल है।

वैश्विक वस्तुओं के लिए यह हमेशा बुरा अभ्यास नहीं है । यदि आप जानते हैं कि आप इसे विश्व स्तर पर / हर जगह / हर समय उपयोग करने जा रहे हैं, तो यह कुछ अपवादों में से एक हो सकता है। हालांकि, ग्लोबल्स को आमतौर पर उसी तरह "बुरा अभ्यास" gotoमाना जाता है जिसे बुरा अभ्यास माना जाता है।


2

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


1

आप कुछ भी याद नहीं कर रहे हैं, जहां तक ​​मैं देख सकता हूं। उदाहरण बहुत त्रुटिपूर्ण है। इससे कोई फर्क नहीं पड़ता, अगर सिंगलटन क्लास में कुछ गैर-स्थिर उदाहरण चर होते।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.