أنماط العمارة في C#: لا تدع كودك يتحول إلى سباغيتي
\n\nكل مطور C# يواجه عاجلاً أم آجلاً اللحظة التي يبدأ فيها مشروعه يشبه طبق معكرونة مطهوة أكثر من اللازم. دوال بطول 500 سطر، كلاسات "تعرف كل شيء"، وأخطاء تتكاثر أسرع من الأرانب. هل هذا مألوف؟ حان الوقت للحديث عن أنماط العمارة في C#.
\n\nفي هذه المقالة، لن نلقي محاضرات مملة. سنستعرض أي أنماط العمارة C# تنقذ المشاريع فعلاً، ونعرض أمثلة كود C# ونقدم معايير اختيار واضحة. لنبدأ!
\n\nنمط MVC: كلاسيكي لا يشيخ
\n\nModel-View-Controller (MVC) هو على الأرجح أشهر نمط عمارة في C# لتطبيقات الويب. فكرته الرئيسية هي تقسيم المسؤولية إلى ثلاث ركائز: البيانات (Model)، العرض (View)، ومنطق التحكم (Controller).
\n\nكيف يعمل عملياً؟
\n\nتخيل متجراً إلكترونياً. المستخدم ضغط على زر "أضف إلى السلة" - هذه إشارة لـ Controller. Controller يطلب من Model تحديث البيانات. Model يقول: "تم!". Controller يختار View المناسبة ويرسل لها البيانات الجديدة. View ترسم ببساطة ما استلمته.
\n\nإليك مثال كود C# بسيط لـ ASP.NET Core MVC:
\n\n// Model\npublic class Product\n{\n public int Id { get; set; }\n public string Name { get; set; }\n public decimal Price { get; set; }\n}\n\n// Controller\npublic class ProductController : Controller\n{\n private readonly AppDbContext _context;\n\n public ProductController(AppDbContext context)\n {\n _context = context;\n }\n\n public IActionResult Index()\n {\n var products = _context.Products.ToList();\n return View(products); // View ستقرر بنفسها كيفية عرض القائمة\n }\n}\n\nمتى تستخدم: تطبيقات الويب ذات واجهة مستخدم غنية، حيث تحتاج لفصل منطق العرض عن التحكم. مثالي لـ عمارة تطبيقات C# على ASP.NET Core.
\n\nنمط MVP: لمن يصادق Windows Forms
\n\nModel-View-Presenter (MVP) - الأخ الأكبر لـ MVC، وهو جيد بشكل خاص لتطبيقات سطح المكتب على WinForms أو WPF. الفرق الرئيسي: View هي "دمية" سلبية، بينما Presenter يدير العملية بأكملها.
\n\nمثال لـ WinForms
\n\n// واجهة View (سلبية)\npublic interface ILoginView\n{\n string UserName { get; }\n string Password { get; }\n event EventHandler LoginClicked;\n void ShowError(string message);\n}\n\n// Presenter (قائد نشط)\npublic class LoginPresenter\n{\n private readonly ILoginView _view;\n private readonly IAuthService _authService;\n\n public LoginPresenter(ILoginView view, IAuthService authService)\n {\n _view = view;\n _authService = authService;\n _view.LoginClicked += OnLoginClicked;\n }\n\n private void OnLoginClicked(object sender, EventArgs e)\n {\n if (_authService.Authenticate(_view.UserName, _view.Password))\n {\n // الانتقال إلى النموذج الرئيسي\n }\n else\n {\n _view.ShowError("اسم مستخدم أو كلمة مرور غير صحيحة");\n }\n }\n}\n\nالميزة: يمكن اختبار View بسهولة عن طريق استبدالها بكائن mock. العيب: يصبح الكود أكثر، لكنه يصبح قابلاً للتنبؤ.
\n\nنمط Repository: إخفاء تعقيد قاعدة البيانات
\n\nنمط Repository C# هو طبقة وسيطة بين منطق الأعمال ومخزن البيانات. بدلاً من توزيع استعلامات SQL في جميع أنحاء الكود، تقوم بإنشاء "مستودع" واحد للتعامل مع الكيانات.
\n\nمثال مع Entity Framework Core
\n\npublic interface IProductRepository\n{\n Task<Product> GetByIdAsync(int id);\n Task<IEnumerable<Product>> GetAllAsync()