التصميم بموجب عقد

مخطط تصميم بالتعاقد

التصميم عن طريق التعاقد ( DbC )، والمعروف أيضًا باسم البرمجة التعاقدية ، والبرمجة عن طريق التعاقد ، والبرمجة عن طريق التصميم التعاقدي ، هو نهج لتصميم البرمجيات .

ينص هذا على أنه ينبغي لمصممي البرمجيات تحديد مواصفات واجهة رسمية ودقيقة وقابلة للتحقق لمكونات البرمجيات ، والتي توسع التعريف العادي لأنواع البيانات المجردة لتشمل الشروط المسبقة واللاحقة والثوابت . وتُعرف هذه المواصفات باسم "العقود"، وفقًا لمجاز مفاهيمي يُشابه شروط والتزامات العقود التجارية .

يفترض نهج DbC أن جميع مكونات العميل التي تستدعي عملية على مكون الخادم ستفي بالشروط المسبقة المحددة على أنها مطلوبة لتلك العملية.

عندما يُعتبر هذا الافتراض محفوفًا بالمخاطر (كما هو الحال في الحوسبة متعددة القنوات أو الموزعة )، يتم اتباع النهج العكسي ، مما يعني أن مكون الخادم يختبر ما إذا كانت جميع الشروط المسبقة ذات الصلة صحيحة (قبل أو أثناء معالجة طلب مكون العميل ) ويرد برسالة خطأ مناسبة إذا لم تكن كذلك.

تاريخ

صاغ برتراند ماير هذا المصطلح في سياق تصميمه للغة البرمجة إيفل ، ووُصف لأول مرة في مقالات متفرقة بدءًا من عام 1986 [ 1 ] [ 2 ] [ 3 ] ، وفي الطبعتين التاليتين (1988، 1997) من كتابه "بناء البرمجيات الموجهة للكائنات" . تقدمت شركة إيفل سوفتوير بطلب لتسجيل العلامة التجارية " التصميم بالتعاقد" في ديسمبر 2003، وحصلت على الموافقة في ديسمبر 2004. [ 4 ] [ 5 ] والمالك الحالي لهذه العلامة التجارية هو شركة إيفل سوفتوير. [ 6 ] [ 7 ]

يستند مفهوم التصميم التعاقدي إلى أعمال التحقق الرسمي ، والمواصفات الرسمية ، ومنطق هوار . وتشمل المساهمات الأصلية ما يلي:

وصف

تتمحور الفكرة الأساسية لمفهوم التصميم القائم على التعاون (DbC) حول استعارة توضح كيفية تعاون عناصر نظام البرمجيات مع بعضها البعض على أساس الالتزامات والمنافع المتبادلة . هذه الاستعارة مستوحاة من عالم الأعمال، حيث يتفق "العميل" و"المورد" على "عقد" يحدد، على سبيل المثال، ما يلي:

  • يجب على المورد تقديم منتج معين (التزام) ويحق له أن يتوقع أن يكون العميل قد دفع رسومه (فائدة).
  • يجب على العميل دفع الرسوم (الالتزام) ويحق له الحصول على المنتج (الفائدة).
  • يجب على كلا الطرفين الوفاء بالتزامات معينة، مثل القوانين واللوائح، التي تنطبق على جميع العقود.

وبالمثل، إذا كانت طريقة فئة ما في البرمجة الكائنية توفر وظيفة معينة، فقد تقوم بما يلي:

  • توقع أن يتم ضمان شرط معين عند الدخول بواسطة أي وحدة عميل تستدعيها: الشرط المسبق للطريقة - وهو التزام على العميل، وفائدة للمورد (الطريقة نفسها)، حيث أنه يحرره من الاضطرار إلى التعامل مع الحالات خارج الشرط المسبق.
  • ضمان خاصية معينة عند الخروج: الشرط اللاحق للطريقة - التزام على المورد، ومن الواضح أنه فائدة (الفائدة الرئيسية لاستدعاء الطريقة) للعميل.
  • الحفاظ على خاصية معينة، مفترضة عند الدخول ومضمونة عند الخروج: ثابت الفئة .

يُعادل هذا العقد دلاليًا ثلاثية هوار التي تُضفي الطابع الرسمي على الالتزامات. ويمكن تلخيص ذلك في "الأسئلة الثلاثة" التي يجب على المصمم الإجابة عنها مرارًا وتكرارًا في العقد:

  • ماذا يتوقع العقد؟
  • ما الذي يضمنه العقد؟
  • ما الذي ينص عليه العقد؟

تتيح العديد من لغات البرمجة إمكانية إنشاء تأكيدات من هذا القبيل. مع ذلك، يعتبر تصميم البرمجيات القائم على العقود (DbC) هذه العقود بالغة الأهمية لصحة البرمجيات ، لدرجة أنها يجب أن تكون جزءًا من عملية التصميم. في الواقع، يدعو تصميم البرمجيات القائم على العقود إلى كتابة التأكيدات أولًا . يمكن كتابة العقود من خلال تعليقات الكود ، أو تطبيقها بواسطة مجموعة اختبارات ، أو كليهما، حتى في حال عدم وجود دعم خاص للعقود في لغة البرمجة.

يمتد مفهوم العقد إلى مستوى الطريقة/الإجراء؛ وعادةً ما يحتوي العقد الخاص بكل طريقة على المعلومات التالية:

يُسمح للفئات الفرعية في التسلسل الهرمي للوراثة بتخفيف الشروط المسبقة (ولكن ليس تقويتها) وتقوية الشروط اللاحقة والثوابت (ولكن ليس إضعافها). تُقارب هذه القواعد التنميط الفرعي السلوكي .

جميع العلاقات بين الفئات تتم بين فئات العميل وفئات المورد. يلتزم العميل باستدعاء وظائف المورد دون أن يؤدي ذلك إلى الإخلال بحالة المورد. وبناءً على ذلك، يلتزم المورد بتوفير حالة وبيانات مُعادة لا تُخالف متطلبات حالة العميل.

على سبيل المثال، قد يتطلب مخزن بيانات المورد وجود البيانات فيه عند استدعاء وظيفة الحذف. وبناءً على ذلك، يضمن المورد للعميل أنه عند انتهاء وظيفة الحذف من عملها، سيتم حذف عنصر البيانات من المخزن. ومن بين عقود التصميم الأخرى مفهوم ثبات الفئة . يضمن ثبات الفئة (للفئة المحلية) الحفاظ على حالة الفئة ضمن حدود التفاوت المحددة في نهاية كل تنفيذ للوظيفة.

عند استخدام العقود، يقوم المورد بالتحقق من استيفاء شروط العقد - وهي ممارسة تُعرف باسم البرمجة الهجومية - والفكرة العامة هي أن الكود يجب أن "يفشل بشدة"، مع اعتبار التحقق من العقد بمثابة شبكة الأمان.

تعمل خاصية "الفشل الصعب" في DbC على تبسيط عملية تصحيح سلوك العقد، حيث يتم تحديد السلوك المقصود لكل طريقة بوضوح.

يختلف هذا النهج اختلافًا جوهريًا عن البرمجة الدفاعية ، حيث يكون المورّد مسؤولاً عن تحديد الإجراء الواجب اتخاذه عند انتهاك شرط مسبق. في أغلب الأحيان، يُصدر المورّد استثناءً لإبلاغ العميل بانتهاك الشرط المسبق، وفي كلتا الحالتين - البرمجة الدفاعية والبرمجة القائمة على التحقق - يجب على العميل تحديد كيفية الاستجابة لذلك. في مثل هذه الحالات، تُسهّل البرمجة القائمة على التحقق مهمة المورّد.

يحدد التصميم التعاقدي أيضاً معايير صحة وحدة البرمجيات:

  • إذا كان الشرط الثابت للفئة والشرط المسبق صحيحين قبل أن يتصل العميل بالمورد، فإن الشرط الثابت والشرط اللاحق سيكونان صحيحين بعد اكتمال الخدمة.
  • عند إجراء مكالمات مع مورد، يجب ألا تنتهك وحدة البرمجيات الشروط المسبقة للمورد.

يُمكن للتصميم التعاقدي أن يُسهّل إعادة استخدام الشيفرة البرمجية، إذ أن عقد كل جزء منها موثق بالكامل. ويمكن اعتبار عقود الوحدة البرمجية بمثابة توثيق برمجي لسلوك تلك الوحدة.

يبدو التصميم التعاقدي، في لغة C++ على سبيل المثال، كما يلي: [ 8 ] [ 9 ]

int f ( const int x ) pre ( x != 1 ) // تأكيد شرط مسبق post ( r : r == x && r != 2 ) // تأكيد شرط لاحق؛ r هو اسم كائن نتيجة f { contract_assert ( x != 3 ); // عبارة تأكيد return x ; }

الآثار المترتبة على الأداء

لا يجوز انتهاك شروط العقد أثناء تنفيذ برنامج خالٍ من الأخطاء. ولذلك، عادةً ما يتم التحقق من العقود فقط في وضع التصحيح أثناء تطوير البرمجيات. وفي وقت لاحق عند الإصدار، يتم تعطيل عمليات التحقق من العقود لتحقيق أقصى قدر من الأداء.

في العديد من لغات البرمجة، يتم تنفيذ العقود باستخدام assert . يتم تعطيل التأكيدات افتراضيًا في وضع الإصدار في C/C++، وبالمثل يتم تعطيلها في C# [ 10 ] و Java.

سيؤدي تشغيل مترجم بايثون باستخدام " -O " (اختصارًا لـ "optimize") كوسيط إلى عدم إصدار مولد كود بايثون أي بايت كود للتأكيدات. [ 11 ]

يؤدي هذا بشكل فعال إلى إلغاء تكاليف وقت التشغيل للتأكيدات في كود الإنتاج - بغض النظر عن عدد التأكيدات المستخدمة في التطوير والتكلفة الحسابية لها - حيث لن يتم تضمين مثل هذه التعليمات في الإنتاج بواسطة المترجم.

العلاقة باختبار البرمجيات

لا يحل التصميم التعاقدي محل استراتيجيات الاختبار التقليدية، مثل اختبار الوحدات واختبار التكامل واختبار النظام . بل إنه يكمل الاختبار الخارجي باختبارات ذاتية داخلية يمكن تفعيلها للاختبارات المعزولة وفي كود الإنتاج أثناء مرحلة الاختبار.

تكمن ميزة الاختبارات الذاتية الداخلية في قدرتها على اكتشاف الأخطاء قبل ظهورها كنتائج غير صحيحة يلاحظها العميل. وهذا يؤدي إلى اكتشاف الأخطاء بشكل أسرع وأكثر دقة.

يمكن اعتبار استخدام التأكيدات شكلاً من أشكال اختبار أوراكل ، وهي طريقة لاختبار التصميم من خلال تنفيذ العقد.

الدعم اللغوي

اللغات التي تدعمها اللغات الأصلية

تشمل اللغات التي تُنفذ معظم ميزات DbC بشكل أصلي ما يلي:

علاوة على ذلك، فإن مجموعة الأساليب القياسية في نظام كائنات Common Lisp تحتوي على مؤهلات الأساليب :before، :afterوالتي :aroundتسمح بكتابة العقود كأساليب مساعدة، من بين استخدامات أخرى.

انظر أيضاً

ملحوظات

  1. ماير، برتراند: التصميم بالتعاقد ، التقرير الفني TR-EI-12/CO، شركة هندسة البرمجيات التفاعلية، 1986
  2. ماير، برتراند: التصميم بالتعاقد ، في كتاب التقدم في هندسة البرمجيات الموجهة للكائنات ، تحرير د. ماندريولي وب. ماير، برنتيس هول، 1991، الصفحات 1-50
  3. ماير، برتراند: " تطبيق "التصميم عن طريق العقد" "، في مجلة الكمبيوتر (IEEE)، 25، 10، أكتوبر 1992، ص 40-51.
  4. "تسجيل مكتب براءات الاختراع والعلامات التجارية بالولايات المتحدة الأمريكية لـ "التصميم بموجب عقد""تمت أرشفة هذا النص من المصدر الأصلي بتاريخ 21 ديسمبر 2016. تم الاطلاع عليه بتاريخ 22 يونيو 2009 .
  5. "تسجيل مكتب براءات الاختراع والعلامات التجارية بالولايات المتحدة للتصميم الجرافيكي الذي يحمل عبارة "تصميم بموجب عقد""تمت أرشفة هذا النص من المصدر الأصلي بتاريخ 21 ديسمبر 2016. تم الاطلاع عليه بتاريخ 22 يونيو 2009 .
  6. "حالة العلامة التجارية واسترجاع المستندات - 78342277" . طلب ​​تسجيل العلامة التجارية واسترجاع بيانات التسجيل لدى مكتب براءات الاختراع والعلامات التجارية الأمريكي .
  7. "حالة العلامة التجارية واسترجاع المستندات - 78342308" . طلب ​​تسجيل العلامة التجارية واسترجاعها من مكتب براءات الاختراع والعلامات التجارية الأمريكي .
  8. ^ جوشوا بيرن. تيمور دوملر؛ أندريه كرزمينسكي (13 فبراير 2025). "عقود C++" (PDF) . open-std.org . مجموعة العمل 22.
  9. 1 2 "تأكيدات العقد (منذ C++26)" . cppreference.com . cppreference . تم الاطلاع عليه في 9 نوفمبر 2025 .
  10. "التأكيدات في التعليمات البرمجية المُدارة" . شبكة مطوري مايكروسوفت . 15 نوفمبر 2016. مؤرشف من الأصل في 22 أغسطس 2018.
  11. وثائق بايثون الرسمية، عبارة التأكيد
  12. برايت، والتر (1 نوفمبر 2014). "لغة البرمجة D، البرمجة التعاقدية" . ديجيتال مارس . تم الاسترجاع في 10 نوفمبر 2014 .
  13. هودجز، نيك. "اكتب كودًا أنظف وأعلى جودة باستخدام عقود الفئات في دلفي بريزم" . إمباركاديرو تكنولوجيز. مؤرشف من الأصل في 26 أبريل 2021. تم الاطلاع عليه في 20 يناير 2016 .
  14. فيندلر، فيليسين عقود الدوال ذات الرتبة العليا
  15. "وثائق مكتبة Scala القياسية - التأكيدات" . EPFL . تم الاطلاع عليه بتاريخ 24-05-2019 .
  16. الكتابة القوية كآلية أخرى "لفرض العقود" في لغة سكالا، انظر المناقشة على scala-lang.org/ .

فهرس

  • ميتشل، ريتشارد، وماكيم، جيم: التصميم بالتعاقد: من خلال الأمثلة ، أديسون-ويسلي، 2002
  • كتاب ويكي يصف تقنية DBC بشكل دقيق وفقاً للنموذج الأصلي.
  • ماكنيل، آشلي: إطار عمل لدلالات العقود السلوكية . وقائع ورشة العمل الدولية الثانية حول نمذجة السلوك: الأسس والتطبيقات (BM-FA '10). ACM، نيويورك، نيويورك، الولايات المتحدة الأمريكية، 2010. تناقش هذه الورقة مفاهيم معممة للعقد وقابلية الاستبدال .