أنماط التصميم في C#: دليل كامل مع أمثلة
أنماط التصميم (design patterns) هي حلول مجربة للمشكلات النمطية في تطوير البرمجيات. في بيئة C# و.NET، تساعد في إنشاء بنية مرنة وقابلة للتوسع والصيانة. في هذه المقالة، سنشرح أربعة أنماط رئيسية: Singleton وFactory Method وObserver وStrategy، مع أمثلة عملية بلغة C#.
لماذا نحتاج أنماط التصميم في C#؟
أنماط التصميم ليست مكتبات أو أطر عمل جاهزة. إنها قوالب مفاهيمية تعمل على:
- تبسيط التواصل — يستخدم المطورون مصطلحات موحدة
- تحسين جودة الكود — تقلل الاقتران وتزيد المرونة
- توفير الوقت — لا حاجة لإعادة اختراع العجلة
- الامتثال لمبادئ SOLID — معظم الأنماط تطبق هذه المبادئ
1. Singleton (المفرد)
الغرض: يضمن وجود مثيل واحد فقط للفئة، ويوفر نقطة وصول عامة إليه.
متى يُستخدم:
- مسجلات الأحداث (Loggers)
- مديري الإعدادات (Configuration Managers)
- مجمع اتصالات قاعدة البيانات
- الذاكرة المؤقتة (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("مرحبًا بالعالم!");