公共方法的前置条件和后置条件构成了该方法与其客户端之间的契约。
1.根据,调用者不应该验证后置条件,被调用方法不应该验证前置条件:
让我们回忆一下平方根函数 sqrt 的前置条件和后置条件,如程序 49.2 所示。调用 sqrt 的函数负责将非负数传递给函数。如果传递了一个负数,平方根函数根本不应该做任何事情来处理它。另一方面,如果将非负数传递给 sqrt,则 sqrt 有责任提供满足后置条件的结果。因此, sqrt 的调用者根本不应该检查或纠正结果。
如果操作的前置条件失败,则归咎于调用者 如果操作的后置条件失败,则归咎于被调用的操作
但正如在另一篇文章中包含的代码中所见,被调用的方法确实验证了先决条件:
/// <summary>Gets the user for the given ID.</summary>
public User GetUserWithIdOf(int id,
UserRepository userRepository) {
// Pre-conditions
if (userRepository == null)
throw new ArgumentNullException(
"userRepository");
if (id <= 0)
throw new ArgumentOutOfRangeException(
"id must be > 0");
User foundUser = userRepository.GetById(id);
// Post-conditions
if (foundUser == null)
throw new KeyNotFoundException("No user with " +
"an ID of " + id.ToString() +
" could be located.");
return foundUser;
}
a)既然满足方法的先决条件是客户的责任,那么被调用的方法是否也应该 检查先决条件是否得到满足?
b) 由于被调用方法有责任交付满足后置条件的结果,调用者是否应该检查后置条件?
2.第一篇文章中提到的一个好处是“前置条件和后置条件可用于在OOP中划分类之间的责任”,我理解这也是说验证前置条件不是被调用方法的责任,它调用者不负责验证postcondition。
但是坚持这样的理念不会使我们的代码更容易受到攻击,因为它盲目地相信对方(对方是调用者或方法)会兑现它的承诺吗?
3.如果调用者/被调用方法不盲目信任对方,那么我们不要失去很多后置条件和前置条件提供的好处,因为现在被调用方法必须承担检查前置条件的责任,调用方必须承担责任验证后置条件?
谢谢
编辑
3.
如果调用者/被调用方法不盲目信任对方,那么我们不要失去很多后置条件和前置条件提供的好处,因为现在被调用方法必须承担检查前置条件的责任,调用方必须承担验证的责任后置条件?
调用者不需要验证后置条件,因为它们应该由被调用的方法来确保。被调用的方法确实需要验证先决条件,因为没有其他方法可以强制执行合同。
a)您是否假设后置条件只应声明/保证返回值是指定类型或null
(如果 返回值可以为空)?除了返回值的类型之外,后置条件还不能说明其他事情(无法通过类型系统验证),例如返回值是否在指定范围内(例如:不能后置条件也说明返回值的类型int
将在 ) 的范围内10-20
?在这种情况下,客户是否还需要检查后置条件?
b)那么我们可以说第一篇文章声称被调用的方法不应该检查先决条件是错误的吗?
2. 编辑
不,后置条件可以是任何东西,而不仅仅是空检查。无论哪种方式,客户端都可以假设后置条件已经过验证,例如,如果合同声明它已被确保,您不需要验证 int 范围。
a) 您之前说过,为了使代码不那么容易受到攻击,需要通过调用方法检查前置条件,但我们是否也不能推断调用方需要验证后置条件(例如,验证返回值是否在后置条件承诺的范围内)为了使调用者的代码不那么容易受到攻击?int
b)如果客户可以盲目地信任后置条件的声明(我会说当后置条件提出返回值在某个范围内的声明时,这是一种盲目信任),为什么被调用方法也不能相信调用者会满足被调用方法的先决条件?