التعريف: يجب أن يكون كيان البرنامج مثل الفئات والوحدات النمطية والوظائف مفتوحًا للامتدادات وإغلاق التعديلات.
أصل المشكلة: خلال دورة حياة البرنامج ، عندما تحتاج الكود الأصلي للبرنامج إلى تعديله بسبب التغييرات والترقيات والصيانة ، قد يتم إدخال الأخطاء في الكود القديم ، وقد يجبرنا أيضًا على إعادة صياغة الوظيفة بأكملها ، ويجب إعادة اختبار الكود الأصلي.
الحل: عندما يحتاج البرنامج إلى التغيير ، حاول تحقيق التغيير من خلال توسيع سلوك كيان البرنامج ، بدلاً من تعديل التعليمات البرمجية الحالية.
مبدأ الفتح والإغلاق هو مبدأ التصميم الأساسي في التصميم الموجهة للكائنات ، والذي يوجهنا كيفية إنشاء نظام مستقر ومرن. قد يكون مبدأ الفتح والإغلاق هو التعريف الأكثر غموضًا لمبادئ نمط التصميم الستة. يخبرنا فقط أن نفتح وإغلاق التعديلات ، ولكن كيف يمكننا الانفتاح والإغلاق وعدم إخبارنا بوضوح. في الماضي ، إذا أخبرني أحدهم ، "يجب أن تلتزم بمبدأ الانفتاح والإغلاق عند التصميم" ، فسأشعر أنه لم يقل أي شيء ، لكن يبدو أنه قال كل شيء. لأن مبدأ الفتح والإغلاق فارغ للغاية.
بعد التفكير بعناية وقراءة العديد من المقالات حول أنماط التصميم ، لم أكن أخيرًا فهمًا صغيرًا لمبدأ الفتح والإغلاق. في الواقع ، نتبع المبادئ الخمسة الأولى لأنماط التصميم ، والغرض من استخدام 23 أنماط التصميم هو اتباع المبادئ الافتتاحية والإغلاق. بمعنى آخر ، طالما نلتزم بالمبادئ الخمسة الأولى ، فإن البرنامج المصمم سوف يتوافق بشكل طبيعي مع المبادئ الافتتاحية والإغلاق. يشبه هذا المبدأ الافتتاحي والإغلاق "متوسط النتيجة" لدرجة الامتثال للمبادئ الخمسة الأولى. إذا تم اتباع المبادئ الخمسة السابقة بشكل جيد ، فستكون متوسط النتيجة أعلى بشكل طبيعي ، مما يعني أن مبادئ فتح البرامج وإغلاقها يتم متابعتها جيدًا ؛ إذا لم يتم الالتزام بالمبادئ الخمسة السابقة ، فهذا يعني أن المبادئ الافتتاحية والإغلاق لا يتم الالتزام بها.
في الواقع ، يعتقد المؤلف أن مبدأ الفتح والإغلاق ليس أكثر من التعبير عن المعنى: بناء إطار عمل مع التجريد وتوسيع التفاصيل مع التنفيذ. نظرًا للمرونة والقدرة الواسعة للتجريد ، طالما أن التجريد معقول ، يمكن الحفاظ على استقرار بنية البرنامج بشكل أساسي. للحصول على التفاصيل المتغيرة في البرنامج ، نستخدم فئة التنفيذ المستمدة من الملخص إلى تمديد. عندما يحتاج البرنامج إلى التغيير ، نحتاج فقط إلى إعادة تشكيل فئة التنفيذ وفقًا لاحتياجات تمديدها. بطبيعة الحال ، فإن الفرضية هي أن تجريدنا يجب أن يكون معقولًا ويجب أن نكون تطلعيًا وتبصر على التغييرات في الطلب.
في تعريف مبدأ الافتتاح والإغلاق ، قد يشير كيان البرنامج إلى وحدة برامج أو هيكل محلي يتكون من فئات متعددة أو فئة مستقلة.
يحتاج أي برنامج إلى مواجهة مشكلة مهمة ، أي أن احتياجاتهم ستتغير مع مرور الوقت. عندما يحتاج نظام البرمجيات إلى مواجهة احتياجات جديدة ، يجب أن نبذل قصارى جهدنا لضمان استقرار إطار تصميم النظام. إذا كان تصميم البرامج يتوافق مع مبدأ الفتح والإغلاق ، فقد يكون من المريح للغاية توسيع النظام ، وليس هناك حاجة لتعديل التعليمات البرمجية الموجودة عند التوسع ، بحيث يكون لنظام البرمجيات استقرار واستمرارية أفضل مع وجود القدرة على التكيف والمرونة. نظرًا لأن مقياس البرمجيات يصبح أكبر وأكبر ، تصبح عمر البرنامج أطول وتصبح تكاليف صيانة البرامج أعلى وأعلى ، وأصبح تصميم أنظمة البرمجيات التي تلبي مبادئ الافتتاح والإغلاق ذات أهمية متزايدة.
من أجل تلبية مبدأ الفتح والإغلاق ، من الضروري تصميم النظام بشكل مجردة ، والتجريد هو مفتاح مبدأ الفتح والإغلاق. في لغات البرمجة مثل Java و C#، يمكن تعريف طبقة التجريد المستقرة نسبيًا للنظام ، ويمكن نقل سلوكيات التنفيذ المختلفة إلى طبقة التنفيذ المحددة لإكمالها. في العديد من لغات البرمجة الموجهة للكائنات ، يتم توفير آليات مثل الواجهات والفئات المجردة ، والتي يمكن من خلالها تحديد طبقة التجريد للنظام ثم تمديدها من خلال فئات الخرسانة. إذا كنت بحاجة إلى تعديل سلوك النظام ، فلا داعي لإجراء أي تغييرات على طبقة التجريد. تحتاج فقط إلى إضافة فئات ملموسة جديدة لتنفيذ وظائف أعمال جديدة ، وذلك لتوسيع وظائف النظام دون تعديل الرموز الموجودة ، وتلبية متطلبات مبدأ الافتتاح والإغلاق.
يمكن لنظام CRM الذي تم تطويره بواسطة Sunny Software أن يعرض أنواعًا مختلفة من المخططات ، مثل المخططات الفطيرة والمخططات البار. لدعم طرق عرض المخططات المتعددة ، يتم عرض خطة التصميم الأصلية في الشكل أدناه:
يوجد مقتطف الكود التالي في طريقة Display () لفئة chartdisplay:
...... if (type.equals ("pie")) {piechart chart = new piechart () ؛ chart.display () ؛ } آخر إذا (type.equals ("bar")) {barchart Chart = new Barchart () ؛ chart.display () ؛ } ...... في هذا الرمز ، إذا كنت بحاجة إلى إضافة فئة مخطط جديدة ، مثل Linechart ، فأنت بحاجة إلى تعديل الكود المصدري لطريقة Display () لفئة chartdisplay وإضافة منطق حكم جديد ، ينتهك مبدأ الفتح والإغلاق.
تم إعادة تشكيل النظام الآن لجعله يتوافق مع مبدأ الفتح والإغلاق.
في هذا المثال ، نظرًا لأن كل فئة مخطط مبرمجة في طريقة Display () لفئة ChartDisplay ، فإن إضافة فئة مخطط جديدة يجب أن تعدل الكود المصدري. يمكن إعادة تمثيل النظام بطريقة مجردة ، بحيث لا توجد حاجة لتعديل الكود المصدري عند إضافة فئات مخطط جديدة. الطرق المحددة هي كما يلي:
(1) أضف فئة مخطط مجردة AbstractChart ، واستخدم فئات المخططات الخرسانية المختلفة مثل فئاتها الفرعية ؛
(2) تتم برمجة فئة ChartDisplay لفئات المخططات التجريدية ، ويقرر العميل المخطط المحدد الذي يجب استخدامه.
يظهر الهيكل بعد إعادة الإعمار في الشكل أدناه:
في الشكل 2 ، نقدم برمجة فئة المخطط التجريدي AbstractChart ، ويتم برمجة ChartDisplay لفئة المخطط التجريدي ، ويقوم العميل بتعيين كائن مخطط محدد من خلال طريقة setChart (). في طريقة العرض () من chartdisplay ، يتم استدعاء طريقة العرض () لكائن الرسم البياني لعرض المخطط. إذا كنت بحاجة إلى إضافة مخطط جديد ، مثل Linechart ، فأنت بحاجة فقط إلى استخدام Linechart كفئة فرعية من AbstractChart وضخ كائن Linechart في chartdisplay على العميل ، دون تعديل الكود المصدري لمكتبة الفئة الحالية.
ملاحظة: نظرًا لأن ملفات التكوين بتنسيقات مثل XML والخصائص هي ملفات نصية عادي ، يمكن تحريرها مباشرة من خلال محرر VI أو المفكرة دون تجميع ، في تطوير البرمجيات ، لا يعتبر تعديل ملفات التكوين عمومًا تعديلًا لرمز مصدر النظام. إذا كان النظام يتضمن تعديل ملف التكوين فقط عند تمديده ، ولم يقم رمز Java الأصلي أو رمز C# بإجراء أي تعديلات ، يمكن اعتبار النظام نظامًا يتوافق مع مبدأ الفتح والإغلاق.