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/