C# में डिज़ाइन पैटर्न: उदाहरणों के साथ पूर्ण गाइड
डिज़ाइन पैटर्न (design patterns) सॉफ्टवेयर विकास में सामान्य समस्याओं के सिद्ध समाधान हैं। C# और .NET इकोसिस्टम में, वे लचीला, स्केलेबल और मेंटेन करने योग्य आर्किटेक्चर बनाने में मदद करते हैं। इस लेख में, हम C# में वास्तविक उदाहरणों के साथ चार प्रमुख पैटर्न: Singleton, Factory Method, Observer और Strategy पर चर्चा करेंगे।
C# में डिज़ाइन पैटर्न की आवश्यकता क्यों है?
पैटर्न तैयार लाइब्रेरी या फ्रेमवर्क नहीं हैं। ये वैचारिक टेम्पलेट हैं जो:
- संचार को सरल बनाते हैं — डेवलपर्स एक समान शब्दावली का उपयोग करते हैं
- कोड की गुणवत्ता बढ़ाते हैं — युग्मन (coupling) कम करते हैं और लचीलापन बढ़ाते हैं
- समय बचाते हैं — पहिए का पुनः आविष्कार करने की आवश्यकता नहीं है
- SOLID सिद्धांतों का पालन करते हैं — अधिकांश पैटर्न इन सिद्धांतों को लागू करते हैं
1. Singleton (सिंगलटन)
उद्देश्य: यह सुनिश्चित करता है कि एक क्लास का केवल एक इंस्टेंस हो, और उस तक पहुंचने के लिए एक वैश्विक बिंदु प्रदान करता है।
कब उपयोग करें:
- लॉगर (Loggers)
- कॉन्फ़िगरेशन मैनेजर (Configuration managers)
- डेटाबेस कनेक्शन पूल (Database connection pool)
- कैश (Caches)
C# उदाहरण (थ्रेड-सेफ इम्प्लीमेंटेशन):
public sealed class ConfigurationManager{ private static readonly Lazy<ConfigurationManager> _instance = new Lazy<ConfigurationManager>(() => new ConfigurationManager());
private readonly Dictionary<string, string> _settings;
private ConfigurationManager() { _settings = new Dictionary<string, string> { { "ConnectionString", "Server=localhost;Database=myDb" }, { "ApiKey", "12345-ABCDE" } }; }
public static ConfigurationManager Instance => _instance.Value;
public string GetSetting(string key) { return _settings.TryGetValue(key, out var value) ? value : null; }}
// उपयोगvar config = ConfigurationManager.Instance;Console.WriteLine(config.GetSetting("ConnectionString"));लाभ:
- एकमात्र इंस्टेंस तक नियंत्रित पहुंच
- आलसी इनिशियलाइज़ेशन (Lazy<T>)
- बिना लॉक के थ्रेड-सुरक्षा
2. Factory Method (फैक्टरी मेथड)
उद्देश्य: ऑब्जेक्ट बनाने के लिए एक इंटरफ़ेस परिभाषित करता है, लेकिन सबक्लास को बनाए जाने वाले ऑब्जेक्ट के प्रकार को बदलने की अनुमति देता है।
कब उपयोग करें:
- जब ऑब्जेक्ट का विशिष्ट प्रकार पहले से ज्ञात न हो
- जब ऑब्जेक्ट बनाने के लिए जटिल तर्क की आवश्यकता हो
- निर्माण और उपयोग कोड को अलग करने के लिए
C# उदाहरण:
// एब्सट्रैक्ट प्रोडक्टpublic interface ILogger{ void Log(string message);}
// कंक्रीट प्रोडक्टpublic class FileLogger : ILogger{ public void Log(string message) => File.AppendAllText("log.txt", $"{DateTime.Now}: {message}");}
public class ConsoleLogger : ILogger{ public void Log(string message) => Console.WriteLine($"{DateTime.Now}: {message}");}
// फैक्टरी मेथड के साथ क्रिएटरpublic abstract class LoggerFactory{ public abstract ILogger CreateLogger(); public void LogMessage(string message) { var logger = CreateLogger(); logger.Log(message); }}
public class FileLoggerFactory : LoggerFactory{ public override ILogger CreateLogger() => new FileLogger();}
public class ConsoleLoggerFactory : LoggerFactory{ public override ILogger CreateLogger() => new ConsoleLogger();}
// उपयोगLoggerFactory factory = new ConsoleLoggerFactory();factory.LogMessage("नमस्ते, दुनिया!");