سؤال

هل تستخدم Design by Contract بشكل احترافي؟هل هو شيء يتعين عليك القيام به منذ بداية المشروع، أم يمكنك تغيير التروس والبدء في دمجه في دورة حياة تطوير البرامج لديك؟ما هي إيجابيات/سلبيات نهج التصميم الذي وجدته؟

جئت عبر التصميم حسب العقد النهج في دورة مدرسة الدراسات العليا.في البيئة الأكاديمية، بدا أنها تقنية مفيدة جدًا.لكنني لا أستخدم Design by Contract حاليًا بشكل احترافي، ولا أعرف أي مطورين آخرين يستخدمونه.سيكون من الجيد أن نسمع عن استخدامه الفعلي من جمهور SO.

هل كانت مفيدة؟

المحلول

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

// @returns null iff x = 0
public foo(int x) {
  ...
}

ويحولها إلى اختبارات وحدة تم إنشاؤها، مثل ذلك:

public test_foo_returns_null_iff_x_equals_0() {
  assertNull foo(0);
}

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

نصائح أخرى

يمكنك حقًا تقدير التصميم بموجب العقد عندما يكون لديك واجهة بين التطبيقات التي يجب أن تتحدث مع بعضها البعض.

بدون العقود، يصبح هذا الوضع سريعًا لعبة إلقاء اللوم على اللاعبين.تستمر الفرق في توجيه الاتهامات ذهابًا وإيابًا ويضيع قدر كبير من الوقت.

مع العقد، اللوم واضح.

هل المتصل مستوفي للشروط المسبقة؟إذا لم يكن الأمر كذلك، يحتاج فريق العميل إلى إصلاحه.

بالنظر إلى طلب صالح، هل استوفى المستلم الشروط البريدية؟إذا لم يكن الأمر كذلك، يحتاج فريق الخادم إلى إصلاح ذلك.

هل التزم الطرفان بالعقد ولكن النتيجة غير مرضية؟العقد غير كاف ويجب تصعيد المشكلة.

ولهذا لا تحتاج إلى تنفيذ العقود في شكل تأكيدات، بل تحتاج فقط إلى التأكد من توثيقها والاتفاق عليها من قبل جميع الأطراف.

إذا نظرت إلى STL، وboost، وMFC، وATL والعديد من المشاريع مفتوحة المصدر، يمكنك أن ترى أن هناك الكثير من عبارات ASSERTION وهذا يجعل المشروع يمضي قدمًا بشكل أكثر أمانًا.

التصميم حسب العقد!إنه يعمل حقًا في منتج حقيقي.

فرانك كروجر يكتب:

جايوس:يتم طرح استثناء Null Pointer لك تلقائيًا في وقت التشغيل، وليس هناك فائدة من اختبار تلك الأشياء في مقدمة الوظيفة.

عندي جوابين على هذا:

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

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

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

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

بالنسبة للغات المكتوبة بشكل ضعيف أو اللغات ذات النطاق الديناميكي (PHP وJavaScript)، تعد العقود الوظيفية مفيدة جدًا أيضًا.

بالنسبة لكل شيء آخر، أود أن أرميه جانبًا وأعتمد على مختبري النسخة التجريبية واختبارات الوحدة.

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

يبدو أن نظام النوع الأقوى المقترن بالتصميم حسب العقد هو الطريق الصحيح.نلقي نظرة على المواصفات # على سبيل المثال:

لغة البرمجة Spec#المواصفات# هي امتداد للغة الموجهة للكائن C#.يمتد نظام النوع ليشمل أنواعًا غير فائقة واستثناءات محددة.ويوفر عقود الطريقة في شكل شروط ما قبل وبعد أن تكون مثبّات الكائنات.

يعد كل من اختبار الوحدة والتصميم حسب العقد من أساليب الاختبار القيمة في تجربتي.

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

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

لم أجد مجموعة أدوات تغطي جميع متطلبات التصميم الخاصة بي للتصميم عن طريق اختبار العقد في منصة .NET/Microsoft.

في الواقع، لا أستخدم التصميم حسب العقد بشكل يومي.لكني أعلم أنه قد تم دمجه في د اللغة، كجزء من اللغة.

نعم إنها كذلك!في الواقع، منذ بضع سنوات مضت، قمت بتصميم إطار عمل صغير للتحقق من صحة الحجج.كنت أقوم بمشروع SOA، حيث قام النظام الخلفي المختلف بجميع أنواع التحقق من الصحة والتحقق.ولكن لزيادة أوقات الاستجابة (في الحالات التي يكون فيها الإدخال غير صالح، ولتقليل تحميل تلك الأنظمة الخلفية)، بدأنا في التحقق من صحة معلمات الإدخال للخدمات المقدمة.ليس فقط لـ Not Null، ولكن أيضًا لأنماط السلسلة.أو القيم من داخل المجموعات.وكذلك الحالات التي يكون فيها للمعلمات تبعيات فيما بينها.

الآن أدرك أننا قمنا في ذلك الوقت بتنفيذ تصميم صغير من خلال إطار العقد :)

وهذا هو الرابط لمن يهمه الأمر الصغير التحقق من صحة وسيطة جافا نطاق.والذي يتم تنفيذه كحل جافا عادي.

أجد أنه من الواضح أن لغة البرمجة Go لا تحتوي على بنيات تجعل التصميم بموجب عقد ممكنًا.الذعر/التأجيل/الاسترداد ليس كذلك تمامًا لأن منطق التأجيل والاسترداد يجعل من الممكن تجاهل الذعر، وIOW لتجاهل العقد المعطل.ما نحتاجه على الأقل هو شكل من أشكال الذعر الذي لا يمكن علاجه، وهو أمر مؤكد حقًا.أو، في أحسن الأحوال، دعم لغوي مباشر للتصميم من خلال بنيات العقد (الشروط السابقة واللاحقة، والتنفيذ والثوابت الطبقية).ولكن نظرًا لقوة عقلاء اللغة الأصوليين على رأس Go ship، فأنا لا أعطي أي تغيير يذكر في أي من هذا الذي تم إنجازه.

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

وجهة نظري هي أن التأكيد مفيد بطرق عديدة لدرجة أن الاضطرار إلى الرقص حوله قد يكون بمثابة صداع.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top