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

StackOverflow https://stackoverflow.com/questions/1219564

سؤال

أدرك أنه في طريقة DbC، يتم ربط الشروط المسبقة والشروط اللاحقة بالوظيفة.

ما أتساءل عنه هو ما إذا كان هذا ينطبق على وظائف الأعضاء أيضًا.

على سبيل المثال، بافتراض أنني أستخدم الثوابت في بداية ونهاية كل وظيفة عامة، ستبدو وظيفة العضو كما يلي:

يحرر:(تنظيف المثال الخاص بي)

void Charcoal::LightOnFire() {
  invariant();
  in_LightOnFire();

  StartBurning();    
  m_Status = STATUS_BURNING;
  m_Color = 0xCCCCCC;

  return; // last return in body

  out_LightOnFire();
  invariant();
}

inline void Charcoal::in_LightOnFire() {
  #ifndef _RELEASE_
  assert (m_Status == STATUS_UNLIT);
  assert (m_OnTheGrill == true);
  assert (m_DousedInLighterFluid == true);
  #endif
}

inline void Charcoal::out_LightOnFire() {
  #ifndef _RELEASE_
  assert(m_Status == STATUS_BURNING);
  assert(m_Color == 0xCCCCCC);
  #endif
}

// class invariant
inline void Charcoal::invariant() {
  assert(m_Status == STATUS_UNLIT || m_Status == STATUS_BURNING || m_Status == STATUS_ASHY);
  assert(m_Color == 0x000000 || m_Color == 0xCCCCCC || m_Color == 0xEEEEEE);
}

هل من المقبول استخدام الشروط المسبقة والشروط اللاحقة مع الوظائف العامة/العامة فقط واستخدام الثوابت داخل الفصول الدراسية؟

يبدو هذا مبالغة، ولكن ربما يكون مثالي سيئًا.

يحرر:

أليس الشرط اللاحق مجرد فحص لمجموعة فرعية من الثابت؟

في ما سبق، أنا أتبع تعليمات http://www.digitalmars.com/ctg/contract.html تنص على أنه "يتم التحقق من الثابت عند اكتمال مُنشئ الفئة، وفي بداية أداة تدمير الفئة، وقبل تشغيل عضو عام، وبعد انتهاء وظيفة عامة."

شكرًا.

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

المحلول

نعم.

الفئة C ثابت هي خاصية مشتركة لجميع مثيلاتها (الكائنات).يتم تقييم الثابت على أنه صحيح إذا وفقط إذا كان الكائن في حالة صالحة دلاليًا.

قد يحتوي ثابت المصعد على معلومات مثل ASSERT(IsStopped() || Door.IsClosed()), لأنه من غير الصحيح أن يكون المصعد في حالة مختلفة عن حالة التوقف (على سبيل المثال، الصعود) والباب مفتوح.

في المقابل، وظيفة العضو مثل MoveTo(int flat) قد يملك CurrentFlat()==flat ك postcondition;لأنه بعد الاتصال بـ MoveTo(6) فإن المسطح الحالي هو 6.وبالمثل، قد يكون IsStopped() ك شرط مسبق, لأنه (حسب التصميم) لا يمكنك استدعاء وظيفة MoveTo إذا كان المصعد يتحرك بالفعل.أولاً، عليك الاستعلام عن حالتها والتأكد من توقفها ثم استدعاء الوظيفة.

بالطبع قد أكون مبالغًا في تبسيط كيفية عمل المصعد.

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

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

نصائح أخرى

إن قصر العقود في الفئات على الثوابت ليس هو الأمثل.

الشروط المسبقة والشروط اللاحقة ليست مجرد مجموعة فرعية من الثوابت.

إن للثوابت والشروط المسبقة والشروط اللاحقة أدوار مختلفة جدًا.

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

الشروط المسبقة هي التحقق من أن حالة الكائن والوسائط مناسبة لتنفيذ الطريقة. الشروط المسبقة مكملة للثوابت.وهي تغطي التحقق من الوسائط (فحص أقوى من النوع نفسه، أي.ليست فارغة، > 0،..إلخ) ولكن يمكن أيضًا التحقق من الحالة الداخلية للكائن (أياستدعاء file.write("مرحبًا") هو استدعاء صالح فقط إذا كان file.is_rw وfile.is_open صحيحين).

تتحقق الشروط اللاحقة من أن الطريقة قد استوفت التزامها الشروط اللاحقة هي أيضا مكملة للثوابت.بالطبع يجب أن تكون حالة الكائن متماسكة بعد تنفيذ الطريقة، ولكن الشروط اللاحقة تتحقق من تنفيذ الإجراء المتوقع (أي تنفيذ الإجراء المتوقع).يجب أن تكون نتيجة list.add(i) أن list.has(i) صحيحة وlist.count = old list.count + 1).

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

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

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

وبطبيعة الحال، والقيام في المتغيرات التي تنص عنصر منطقي إما صحيحة أو خاطئة لا طائل قليلا - نظام نوع يضمن

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