oop - 得墨忒耳定律和类构造函数

标签 oop law-of-demeter

Law of Demeter不会阻止将对象传递给类构造函数。但是,它确实禁止稍后取回相同的对象并在其上调用方法以获取标量值。相反,应该创建一个返回标量值的代理方法。我的问题是,为什么将一个对象传递给类构造函数是可以接受的,但以后再取回同一个对象并从中提取一个值是 Not Acceptable ?

最佳答案

因为得墨忒耳定律说你不应该设计一个对象的外部接口(interface),让它看起来好像是由具有已知接口(interface)的某些其他对象组成的,客户可以捕获和访问。

您将一个对象传递给构造函数以告诉您的新对象如何表现,但是该对象是否保留该参数对象,或者保留它的副本,或者只是查看它一次并忘记它曾经存在过,这与您无关.通过使用 getMyParameterBack 方法,您已经 promise 所有 future 的实现能够按需生成整个对象,并且所有客户端都与两个接口(interface)而不是一个接口(interface)耦合。

例如,如果您将 URL 参数传递给 HTTPRequest 对象的构造函数,那么这并不意味着 HTTPRequest 应该有一个 getURL 方法,该方法返回一个 URL 对象,然后调用者将在该对象上调用 getProtocol、getQueryString 等。如果有人拥有 HTTPRequest 对象的人可能想知道请求的协议(protocol),他们应该(法律规定)通过在他们拥有的对象上调用 getProtocol 来找出答案,而不是在他们碰巧知道 HTTPRequest 正在内部存储的其他对象上。

这个想法是为了减少耦合 - 如果没有 Demeter 法则,用户必须知道 HTTPRequest 和 URL 的接口(interface)才能获得协议(protocol)。有了法律,他们只需要HTTPRequest的接口(interface)。并且 HTTPRequest.getProtocol() 显然可以返回“http”,而不需要一些 URL 对象参与讨论。

有时请求对象的用户恰好是创建它的人,因此也使用 URL 接口(interface)来传递参数这一事实既不存在也不存在。并非所有 HTTPRequest 对象的用户都会自己创建它们。因此,根据法律有权访问 URL 因为他们自己创建 URL 的客户可以这样做,而不是从请求中获取它。没有创建 URL 的客户端不能。

就我个人而言,我认为通常以简单形式陈述的得墨忒耳法则已经破解。他们是否认真地说,如果我的对象有一个字符串 Name 字段,并且我想知道 Name 是否包含任何非 ASCII 字符,那么我必须在我的对象上定义一个 NameContainsNonASCIICharacters 方法而不是查看字符串本身,或者向采用回调函数的类添加一个 visitName 函数,以便通过确保字符串是我编写的函数的参数来解决限制?这根本不会改变耦合,它只是用访问者方法替换了 getter 方法。如果我想操纵返回值,是否每个返回整数的类都有一整套算术运算? getPriceMultipliedBy(int n)?肯定不是。

它的用处在于,当你破坏它时,你可以问自己为什么要破坏它,以及是否可以通过不破坏它来设计更好的界面。通常你可以,但实际上这取决于你在谈论什么类型的对象。某些接口(interface)可以安全地与大量代码耦合——比如整数、字符串,甚至 URL,它们代表了广泛使用的概念。

关于oop - 得墨忒耳定律和类构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1151381/

相关文章:

java - 如何添加priceAfterDiscount的公共(public)实例方法,该方法返回折扣后的价格

php - 从过程函数到 OOP 类(一种特定情况)

java - 避免带有模式的 getter 链

design-patterns - 长对象调用链有天生的错误吗?

oop - 封装原理

php - 函数内部定义的常量无法通过类名访问,请参阅代码

javascript - OO JS继承和原型(prototype)

typescript - 如何重载泛型方法以使其在 Typescript 中不那么泛型?

java - 这是否违反了德墨忒尔法则?与可读代码

c++ - 得墨忒耳法则和异界转移