除合同外还要了解实施情况?

时间:2018-01-29 15:40:44

标签: oop architecture solid-principles

SOLID中的L和D都鼓励我们针对合同进行编程,而不是实际的实施。但是,这是否意味着接口消费者不应该知道实现,或者仅仅是他不应该依赖于实现明确未在合同中声明的内容?

我的意思是,我们可以有一个方法在DB中创建一个新的NumericParameter,但它的界面只能说明这一点!它并没有说NumericParameter实际上是跨越2个表的继承实体,或者该方法还创建了一个更多相关实体来保存有关创建实体的更多数据。这些是实施细节。

很清楚为什么不应该依赖实施做某事。但也许依靠实施 NOT 做某事是否合理(即使它没有在合同中说明?)否则,你将如何修改你的代码呢?每次添加某些活动时,它都可能与您调用的某些其他方法和服务中发生的事件发生冲突。比如,你读了一个数据库行"对于更新",然后调用foo(),然后用一些修改写回一行,但看起来foo()已经对同一行做了一些更改 - 在这非常交易 - 它们将被覆盖。

另一方面,可以改变实施。如果某些消费者依赖它不做某事,那么在某个时刻依赖可能会破坏。意思是,我们不仅要检查从正在编辑的代码中调用的代码,还要检查代码的可能调用者。在触发此代码的任何事务中可能发生的一切,我们必须详细了解。

不知怎的,我认为这是一种气味,但你如何生活没有它?我通常会尝试忽略实现细节,但在多个场合最终会出现一些冲突。

4 个答案:

答案 0 :(得分:0)

这是“自以为是”的边缘,但我认为

的实际答案
  

他不应该依赖于实施明确没有在合同中说明的内容吗?

是 - 完全。这就是核心元素。编写接口的人也会编写至少一个实现,这是很常见的。在写下界面时,可能已经设计了一些(至少在你的脑海中)。因此,“了解实施”是您在现实世界中最常无法避免的事情。因此,请更好地关注陈述的第二部分。

除此之外:当你发现合同含糊不清时,不要花时间担心不同的解释。而是将你的精力用于澄清合同,使其变得“足够清楚”实现应该做什么或不做什么。

答案 1 :(得分:0)

我认为SOLID的关键在于您应该尽可能地使用所有原则,而不是单独选择一个或两个。您使用foo()提供的示例是一个问题,因为代码的两个区域处理相同的数据库记录。我的解释是,这违反了SOL中的S.

答案 2 :(得分:0)

  

但这是否意味着界面消费者不应该知道   实施,或者只是他不应该依赖于实施   做一些没有在合同中明确规定的事情?

前者。然而,依赖性是否会使自己无法触及他们甚至不知道客户关心的外部内容?合同不是说'不要动我的奶酪"但是反而"给我一些我期望的形状,无论你做哪种方式"。

我看到的唯一其他答案是使用纯(无副作用)函数,但我们不再是OOP领域了。

答案 3 :(得分:0)

好的,让我总结一下所收集的智慧。

1)通常,方法的所有重要影响都是其合同的一部分(或者应该是),或者是由环境决定的(就像它在JPA&删除时干扰JPA和#39一样) ; s修改其他一些实体)。如果它是前者,那么合同告诉我们期待什么,如果是后者,开发者应该知道他自己定义的环境的影响。因此,在这两种情况下,他应该知道可能的冲突没有知道实现。一个设计合理的方法几乎不会产生与其合同和环境/设置/等完全无关的一些重大影响,或者至少没有出现在我脑海中的例子,或者这里有其他人提到过。当然,除非那个知道它的人过于亲密并且依赖于它的实现,否则该方法就会被使用;但在这种情况下,我当然必须知道实施情况,我的问题不适用。

2)在我的问题中,我提到了实施细节,例如"跨越几个表的继承实体"和"再创建一个实体"。那么,JPA继承特有的问题是环境的一部分;创建额外实体应该是合同的一部分(如果实体是由其他人推荐的)或不引起任何干扰(如果它是严格的私人事物),或者如果它是某些产品的某种产品则成为环境的一部分"方面"由配置引入最初的原始方法的逻辑。

因此,我原来问题的答案是"无需知道实施细节" (除非你必须使用紧密耦合的课程),并且"给定正确定义的合同和正确设计的方法,你可以没有它,因为你应该知道合同和环境所需要的一切"。