如果通过合同进行设计,除了成员函数中的不变量之外还需要先决条件和后置条件吗?

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 表示,<!> quot;当类构造函数完成时,在类析构函数的开头,运行公共成员之前以及公共函数完成之后,将检查不变量。 QUOT <!>;

感谢。

有帮助吗?

解决方案

C类的不变是其所有实例(对象)的公共属性。当且仅当对象处于语义有效状态时,不变量的计算结果为真。

电梯的不变量可能包含ASSERT(IsStopped() || Door.IsClosed())等信息,因为电梯处于不同于停止状态(例如,上升)和门打开的状态无效。

相反,MoveTo(int flat)等成员函数可能CurrentFlat()==flat作为后置条件;因为在调用MoveTo(6)之后,当前的平面是6.同样,它可能IsStopped()作为前提条件,因为(取决于设计)你不能调用函数MoveTo电梯已经在移动。首先,您必须查询其状态,确保它已停止,然后调用该函数。

当然,我可能完全过分简化了电梯的运作方式。

无论如何,一般来说,先决条件和后置条件作为不变条件是没有意义的;电梯不需要在6楼处于有效状态。

可以在这里找到一个更简洁的例子:截取和属性:Sasha Goldshtein的按合同设计的样本

其他提示

将类中的合同限制为不变量并非最佳。

前提条件和后置条件不仅仅是不变量的一个子集。

不变量,前提条件和后置条件具有非常不同的作用。

不变量确认对象的内部一致性。它们应该在构造函数的末尾以及每次方法调用之前和之后有效。

前置条件是检查对象和参数的状态是否适合执行方法。前提条件是不变量的补充。它们涵盖了对参数的检查(更强的检查类型本身,即非空,<!> gt; 0,...等),但也可以检查对象的内部状态(即对file.write的调用(<只有当file.is_rw和file.is_open为真时,em> <!>“hello <!>”才是有效的调用。)

后期条件正在使该方法满足其义务后置条件也是不变量的补充。当然,对象的状态必须在方法执行后保持一致,但后置条件检查是否执行了预期的操作(即list.add(i)应该具有list.has(i)为真的结果和list.count = old list.count + 1)。

嗯,不变量的意思是它始终描述了对象的真实。在这种情况下,烤架上是否有东西(两者之间没有任何东西)。它们通常描述对象整个状态的属性。

前置条件和后置条件描述了在方法执行之前就已经存在的事情,以及之后,并且将关注仅仅应该被方法触及的状态。据推测,这与对象的状态不同。前后条件可能被认为是描述方法的足迹 - 正是它所需要的,只是它触及的内容。

所以,对于具体的问题,这些想法做了不同的事情,所以你可能都想要两者。你当然不能只使用不变量而不是前后条件 - 在这个例子中,对象不变量的一部分是<!>“;有些东西在格栅上或者不是<!>”,但是lightOnFire的前提条件需要知道这个项目在烤架上。你永远无法从对象不变量中推断出这一点。确实,从前置条件和后置条件以及已知的开始状态,您可以(假设对象结构只能通过方法变化,并且前后条件描述所有环境变化),推断对象不变。但是,这可能很复杂,当您在语言<!>中指出<!>“;”时,更容易提供两者。

当然,在声明布尔项的变体中执行true或false是有点无意义的 - 类型系统确保了。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top