domain-driven-design - 客户端是否应该检查后置条件/调用的方法是否应该检查前置

公共(public)方法的前置条件后置条件构成了该方法与其客户端之间的契约。

1.根据to ,调用者不应该验证后置条件并且被调用的方法不应该验证前提条件:

Let us recall the precondition and the postcondition of the square root function sqrt, as shown in Program 49.2. A function that calls sqrt is responsible to pass a non-negative number to the function. If a negative number is passed, the square root function should do nothing at all to deal with it. If, on the other hand, a non-negative number is passed to sqrt, it is the responsibility of sqrt to deliver a result which fulfills the postcondition. Thus, the caller of sqrt should do nothing at all to check or rectify the result.

Blame the caller if a precondition of an operation fails Blame the called operation if the postcondition of an operation fails

但如 another article 中包含的代码所示, 被调用的方法确实验证了先决条件:

/// <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中划分类之间的责任”,我理解为也不是被调用方法有责任验证前提条件调用者没有责任验证后置条件

但是坚持这样的哲学并没有使我们的代码更容易受到攻击,因为它盲目地相信另一方(另一方是调用者方法)会兑现 promise 吗?

3.如果调用方/被调用方不盲目地信任另一方,那么我们不会失去后置条件前置条件提供的很多好处,因为现在被调用方法 必须承担检查前置条件 的责任,调用方 必须承担验证后置条件 的责任?

谢谢

编辑

3.

If caller/called method doesn't blindly trust other party , then don't we loose much of the benefits provided by postconditions and preconditions, since now called method must take on the responsibility to also check precondition and caller must take on responsibility to verify the postcondition?

调用者不需要验证后置条件,因为它们应该是 由调用的方法确保。调用的方法确实需要验证 前提条件,因为没有其他方式来执行契约(Contract)。

a) 您是否假设后置条件 应该只声明/保证返回值 是指定类型或null(如果返回值是可空)?除了返回值是什么类型之外,后置条件也不能说明其他事情(类型系统无法验证),例如是否返回值指定范围 内(例如:不能后置条件 也声明返回值 类型int 将在 10-20 范围内)?在这种情况下,客户不需要检查后置条件吗?

b) 那么我们可以说第一篇文章声称​​被调用的方法 不应该检查先决条件 是错误的吗?

2。编辑

No, a post condition can be anything, not just a null check. Either way, the client can assume that the post-condition has been verified so that, for example, you don't need to verify the int range if the contract states that it has been ensured.

a) 您之前说过先决条件需要通过被调用的方法进行检查,以降低代码的脆弱性,但我们不能也推断出调用者 需要验证一个后置条件(例如,验证返回的int 值是否在后置条件 promise 的范围内)以便使调用者的代码 不那么脆弱?

b) 如果客户可以盲目地相信后置条件 提出的声明(当后置条件 提出返回值在内部时,我会说这是一种盲目信任一些范围),为什么被调用方法也不能相信调用者会满足被调用方法的先决条件

最佳答案

a) Since it is a responsibility of a client to fulfill the preconditions of a method, should called method also check whether preconditions are fulfilled?

是的,客户端有责任确保满足先决条件,但是被调用的方法必须验证这一点,因此示例中的空检查。

b) Since it is a responsibility of a called method to deliver result which fulfills the postcondition, should the caller check the postcondition?

调用者应该能够依赖被调用方法的契约。在您提供的示例中,方法 GetUserWithIdOf 确保满足后置条件,否则抛出异常。存储库本身没有它总是返回用户的后置条件,因为可能找不到用户。

2.One of the benefits mentioned in first article is that "Preconditions and postconditions can be used to divide the responsibility between classes in OOP", which I understand as also saying that it isn't the responsibility of called method to verify preconditions and it isn't the responsibility of a caller to verify postcondition.

验证前置条件仍然是被调用方法的责任,因为类型系统通常无法验证它们。语言如 Eiffel提供更大程度的静态契约(Contract)验证,在这种情况下,可以利用该语言来执行先决条件。就像在 Java/C# 中一样,您可以强制方法参数属于给定类型,Eiffel 将这种类型的验证扩展到更复杂的契约声明。

But doesn't adhering to such philosophy make our code more vulnerable, since it blindly trusts that the other party ( other party being either a caller or a method ) will deliver on its promise?

是的,这就是必须验证前提条件的原因。

3.If caller/called method doesn't blindly trust other party , then don't we loose much of the benefits provided by postconditions and preconditions, since now called method must take on the responsibility to also check precondition and caller must take on responsibility to verify the postcondition?

调用者不需要验证后置条件,因为它们应该由被调用的方法来确保。被调用的方法确实需要验证先决条件,因为没有其他方式来执行契约。

更新

a) 不,后置条件可以是任何东西,而不仅仅是空检查。无论哪种方式,客户端都可以假定后置条件已得到验证,例如,如果契约(Contract)声明它已得到确保,则您无需验证 int 范围。

b) 我会说是的。引用:

If a negative number is passed, the square root function should do nothing at all to deal with it.

if 表明调用的方法已经进行了某种验证。什么都不做是无声的失败,可以是 anti-pattern .

随后的引述:

Blame the caller if a precondition of an operation fails Blame the called operation if the postcondition of an operation fails

将失败的前提条件归咎于调用者的唯一方法是首先确定前提条件失败。由于被调用方法“拥有”此前提条件,因此它应该是标记失败的最后一站。

更新 2

a,b) 调用者可以信任后置条件的原因是因为被调用方法可以确保后置条件。被调用的方法是声明和拥有合约的方法。被调用方法不能信任调用者的原因是因为没有人保证会满足先决条件。被调用方法不知道它可能拥有的所有各种调用者,因此它必须自行验证。

关于domain-driven-design - 客户端是否应该检查后置条件/调用的方法是否应该检查前置条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16323702/

相关文章:

debugging - 无法为 jruby 运行调试器

owl - owl :Class and owl:Thing?有什么区别

avr - 使用USBASP编程器进行SPI通信

clojure - 为什么我的 clojure.core.logic 非成员函数返回两个值?

python - 制作包含负值的对数标度彩色图

versioning - 执行包装器库的 semver(语义版本控制)的最佳做法是什么?

r - 分位数回归的置信区间是多少?以及如何找到默认以外的内容?

php - scandir 并返回匹配的文件

tablesorter - Jquery 插件相互干扰

python - 用 fabric 模拟 KeyboardInterrupt