खोज…


टिप्पणियों

सिंगलटन डिज़ाइन पैटर्न को कभी-कभी " एंटी पैटर्न " माना जाता है। यह इस तथ्य के कारण है कि इसमें कुछ समस्याएं हैं। आपको अपने लिए तय करना होगा यदि आपको लगता है कि इसका उपयोग करना उचित है। StackOverflow पर इस विषय पर कई बार चर्चा की गई है।

देखें: http://stackoverflow.com/questions/137975/what-is-so-bad-about-singletons

सिंगलटन (C #)

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

थ्रेड-सेफ सिंगलटन पैटर्न

public sealed class Singleton
{
    private static Singleton _instance;
    private static object _lock = new object();
 
    private Singleton()
    {
    }
 
    public static Singleton GetSingleton()
    {
        if (_instance == null)
        {
             CreateSingleton();
        }

        return _instance;
    }

    private static void CreateSingleton()
    {
        lock (_lock )
        {
            if (_instance == null)
            {
                 _instance = new Singleton();
            }
        }
    }
}

जॉन स्कीट एक आलसी, धागा-सुरक्षित सिंगलटन के लिए निम्नलिखित कार्यान्वयन प्रदान करता है:

public sealed class Singleton
{
    private static readonly Lazy<Singleton> lazy =
        new Lazy<Singleton>(() => new Singleton());
    
    public static Singleton Instance { get { return lazy.Value; } }

    private Singleton()
    {
    }
} 

सिंगलटन (जावा)

जावा में सिंगलटन बहुत हद तक # के समान हैं, क्योंकि दोनों भाषाएं ऑब्जेक्ट ओरिएंटेड हैं। नीचे एक एकल वर्ग का एक उदाहरण है, जहां कार्यक्रम के दौरान जीवन का केवल एक ही संस्करण जीवित हो सकता है (मान लें कि कार्यक्रम एक धागे पर काम करता है)

public class SingletonExample {

    private SingletonExample() { }

    private static SingletonExample _instance;

    public static SingletonExample getInstance() {

        if (_instance == null) {
            _instance = new SingletonExample();
        }
        return _instance;
    }
}

यहाँ उस प्रोग्राम का थ्रेड सेफ वर्जन है:

public class SingletonThreadSafeExample {

    private SingletonThreadSafeExample () { }

    private static volatile SingletonThreadSafeExample _instance;

    public static SingletonThreadSafeExample getInstance() {
        if (_instance == null) {
                createInstance();
        }
        return _instance;
    }

    private static void createInstance() {
        synchronized(SingletonThreadSafeExample.class) {
            if (_instance == null) {
                _instance = new SingletonThreadSafeExample();
            }
        }
    }
}

Java में भी एक ऑब्जेक्ट है, जिसे ThreadLocal कहा जाता है, जो थ्रेड आधार पर किसी थ्रेड पर किसी ऑब्जेक्ट का एक एकल उदाहरण बनाता है। यह उन अनुप्रयोगों में उपयोगी हो सकता है जहां प्रत्येक थ्रेड को ऑब्जेक्ट के अपने संस्करण की आवश्यकता होती है

public class SingletonThreadLocalExample {

    private SingletonThreadLocalExample () { }

    private static ThreadLocal<SingletonThreadLocalExample> _instance = new ThreadLocal<SingletonThreadLocalExample>();

    public static SingletonThreadLocalExample getInstance() {
        if (_instance.get() == null) {
            _instance.set(new SingletonThreadLocalExample());
        }
        return _instance.get();
    }
}

यहाँ भी साथ एक सिंगलटन कार्यान्वयन है enum (केवल एक तत्व से युक्त):

public enum SingletonEnum {
    INSTANCE;
    // fields, methods
}

किसी भी Enum वर्ग कार्यान्वयन सुनिश्चित करता है कि इसके प्रत्येक तत्व का केवल एक उदाहरण मौजूद होगा।

बिल पुघ सिंगलटन पैटर्न

बिल पुग सिंग्लटन पैटर्न सिंग्लटन वर्ग के लिए सबसे व्यापक रूप से उपयोग किया जाने वाला तरीका है क्योंकि इसे सिंक्रनाइज़ेशन की आवश्यकता नहीं है

public class SingletonExample {

    private SingletonExample(){}
    
    private static class SingletonHolder{
        private static final SingletonExample INSTANCE = new SingletonExample();
    }
    
    public static SingletonExample getInstance(){
        return SingletonHolder.INSTANCE;
    }
}

निजी आंतरिक स्थैतिक वर्ग का उपयोग करने के साथ धारक को मेमोरी में लोड नहीं किया जाता है जब तक कि कोई गेटइनस्टांस विधि को कॉल नहीं करता है। बिल पुघ समाधान थ्रेड सुरक्षित है और इसे सिंक्रनाइज़ेशन की आवश्यकता नहीं है।


जावा डॉक्यूमेंट टैग के तहत सिंगलेट्स विषय में अधिक जावा सिंगलटन उदाहरण हैं।

सिंगलटन (C ++)

विकी के अनुसार: सॉफ्टवेयर इंजीनियरिंग में, सिंगलटन पैटर्न एक डिज़ाइन पैटर्न है जो किसी कक्षा को एक वस्तु के लिए तत्काल रोक देता है।

सिस्टम में क्रियाओं का समन्वय करने के लिए ठीक एक वस्तु बनाने के लिए यह आवश्यक है।

class Singleton
{
    // Private constructor so it can not be arbitrarily created.
    Singleton()
    {}
    // Disable the copy and move
    Singleton(Singleton const&)            = delete;
    Singleton& operator=(Singleton const&) = delete;
  public:

    // Get the only instance
    static Singleton& instance()
    {
        // Use static member.
        // Lazily created on first call to instance in thread safe way (after C++ 11)
        // Guaranteed to be correctly destroyed on normal application exit.
        static Singleton _instance;

        // Return a reference to the static member.
        return _instance;
    }
};

लावा सिंगलटन व्यावहारिक उदाहरण जावा में

सिंगलटन पैटर्न के लिए वास्तविक जीवन के उपयोग के मामले;

यदि आप एक क्लाइंट-सर्वर एप्लिकेशन विकसित कर रहे हैं, तो आपको ConnectionManager एकल इंस्ट्रक्शन की आवश्यकता होती है, जो क्लाइंट कनेक्शन के जीवन चक्र का प्रबंधन करता है।

ConnectionManager में मूल API:

registerConnection : मौजूदा कनेक्शन की सूची में नया कनेक्शन जोड़ें

closeConnection : क्लाइंट या सर्वर द्वारा ट्रिगर की गई घटना से कनेक्शन को बंद करें

broadcastMessage संदेश: कुछ समय, आपको सभी सब्सक्राइबर क्लाइंट कनेक्शनों को एक संदेश भेजना होगा।

मैं स्रोत कोड का पूर्ण कार्यान्वयन प्रदान नहीं कर रहा हूं क्योंकि उदाहरण बहुत लंबा हो जाएगा। उच्च स्तर पर, कोड इस तरह होगा।

import java.util.*;
import java.net.*;

/* Lazy Singleton - Thread Safe Singleton without synchronization and volatile constructs */
final class  LazyConnectionManager {
    private Map<String,Connection> connections = new HashMap<String,Connection>();
    private LazyConnectionManager() {}
    public static LazyConnectionManager getInstance() {
        return LazyHolder.INSTANCE;
    }
    private static class LazyHolder {
        private static final LazyConnectionManager INSTANCE = new LazyConnectionManager();
    }

    /* Make sure that De-Serailzation does not create a new instance */
    private Object readResolve()  {
        return LazyHolder.INSTANCE;
    }
    public void registerConnection(Connection connection){
        /* Add new connection to list of existing connection */
        connections.put(connection.getConnectionId(),connection);
    }
    public void closeConnection(String connectionId){
        /* Close connection and remove from map */
        Connection connection = connections.get(connectionId);
        if ( connection != null) {
            connection.close();
            connections.remove(connectionId);
        }
    }
    public void broadcastMessage(String message){
        for (Map.Entry<String, Connection> entry : connections.entrySet()){
            entry.getValue().sendMessage(message);            
        }
    }    
}

नमूना सर्वर वर्ग:

class Server implements Runnable{
    ServerSocket socket;
    int id;
    public Server(){
        new Thread(this).start();
    }
    public void run(){
        try{
            ServerSocket socket = new ServerSocket(4567);
            while(true){
                Socket clientSocket = socket.accept();
                ++id;
                Connection connection = new Connection(""+ id,clientSocket);
                LazyConnectionManager.getInstance().registerConnection(connection);    
                LazyConnectionManager.getInstance().broadcastMessage("Message pushed by server:");
            }
        }catch(Exception err){
            err.printStackTrace();
        }
    }
    
}

एकल के लिए अन्य व्यावहारिक उपयोग के मामले:

  1. वैश्विक संसाधनों का प्रबंधन करना जैसे ThreadPool, ObjectPool, DatabaseConnectionPool आदि।
  2. DEBUG,INFO,WARN,ERROR आदि जैसे विभिन्न लॉग स्तरों के साथ अनुप्रयोग डेटा Logging जैसी केंद्रीकृत सेवाएं
  3. वैश्विक RegistryService जहां विभिन्न सेवाओं को स्टार्टअप पर एक केंद्रीय घटक के साथ पंजीकृत किया जाता है। वैश्विक सेवा आवेदन के लिए एक Facade रूप में कार्य कर सकती है

सी # उदाहरण: मल्टीथ्रेडेड सिंगलटन

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

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

using System;

public sealed class Singleton {    
   private static volatile Singleton instance;    
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance    {
      get 
      {
         if (instance == null) 
         {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }    
  } 
}

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

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

संदर्भ: MSDN

स्वीकृतियाँ

[गामा 95] गामा, हेल्म, जॉनसन, और व्लाइसीड्स। डिजाइन पैटर्न: पुन: प्रयोज्य वस्तु-उन्मुख सॉफ्टवेयर के तत्व। एडिसन-वेस्ले, 1995।

[Lea99] ली, डग। जावा में समवर्ती प्रोग्रामिंग, दूसरा संस्करण। एडिसन-वेस्ले, 1999।

[Sells03] बेचता है, क्रिस। "सील चूसो।" sellbrothers.com समाचार। यहां उपलब्ध है: http://www.sellsbrothers.com/news/showTopic.aspx?ixTopic=411

सिंगलटन (PHP)

Phptherightway.com से उदाहरण

<?php
class Singleton
{
    /**
     * @var Singleton The reference to *Singleton* instance of this class
     */
    private static $instance;
    
    /**
     * Returns the *Singleton* instance of this class.
     *
     * @return Singleton The *Singleton* instance.
     */
    public static function getInstance()
    {
        if (null === static::$instance) {
            static::$instance = new static();
        }
        
        return static::$instance;
    }

    /**
     * Protected constructor to prevent creating a new instance of the
     * *Singleton* via the `new` operator from outside of this class.
     */
    protected function __construct()
    {
    }

    /**
     * Private clone method to prevent cloning of the instance of the
     * *Singleton* instance.
     *
     * @return void
     */
    private function __clone()
    {
    }

    /**
     * Private unserialize method to prevent unserializing of the *Singleton*
     * instance.
     *
     * @return void
     */
    private function __wakeup()
    {
    }
}

class SingletonChild extends Singleton
{
}

$obj = Singleton::getInstance();
var_dump($obj === Singleton::getInstance());             // bool(true)

$anotherObj = SingletonChild::getInstance();
var_dump($anotherObj === Singleton::getInstance());      // bool(false)

var_dump($anotherObj === SingletonChild::getInstance()); // bool(true)

सिंगलटन डिज़ाइन पैटर्न (सामान्य रूप से)

नोट: सिंगलटन एक डिज़ाइन पैटर्न है।
लेकिन इसे एक विरोधी पैटर्न भी माना जाता है।

उपयोग करने से पहले एक सिंगलटन के उपयोग को सावधानी से विचार किया जाना चाहिए। आमतौर पर बेहतर विकल्प होते हैं।

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

सृजन पैटर्न के साथ संयोजन में उनका उपयोग करके एकल के साथ मुद्दों को कम किया जा सकता है; ताकि एकल के प्रारंभिक निर्माण को नियंत्रित किया जा सके।



Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow