得墨meter耳定律(也称为最少知识定律)是一种编码原理,它表示模块不应该知道其操作的对象的内部细节。 如果代码依赖于特定对象的内部细节,则很有可能一旦该对象的内部发生更改,它就会被破坏。 由于封装是关于隐藏对象的内部细节并仅公开操作的,因此它还声明了Demeter定律 。 许多Java程序员都犯了一个错误,那就是它使用getter方法公开了对象的内部细节,而这正是知识最少的原则提醒您的地方。 在阅读一本必读的编程书 《罗伯特·C·马丁的清洁代码》时 ,我首先了解了这一原理。 除了本书教给你的许多好处之外, “最起码的原则”是一个原则,我至今仍然记得。 像许多不好的事情一样,由于以流利的风格编写的漂亮方法链,您将很容易违反德米特法则。 从表面上看,它看起来不错,但是一旦您想到了最少知识的原理,便开始看到真实的图画。 在本文中,我们将看到Demeter定律的正式定义,并探索违反该原理的代码段。
根据Demeter定律,对象O的方法M应该仅调用以下类型的方法:
- 对象O本身的方法
- 作为参数传递的Object方法
- 对象的方法,保存在实例变量中
- 在方法M中本地创建的任何对象
更重要的是,方法不应在上面指定的任何后续方法调用返回的对象上调用方法,正如Clean Code所说的“与朋友交谈,而不是与陌生人交谈”。 除了了解面向对象编程的基本概念(例如抽象 , 多态 , 继承和SOLID设计原理)外 ,还值得了解像这样的有用原理,它是通过经验发现的。 在下面的示例中,我们将看到一种方法如何违反上述规则以违反定界符定律。
public class LawOfDelimterDemo {/*** This method shows two violations of "Law of Delimiter" or "Principle of least knowledge".*/public void process(Order o) {// as per rule 1, this method invocation is fine, because o is a argument of process() methodMessage msg = o.getMessage();// this method call is a violation, as we are using msg, which we got from Order.// We should ask order to normalize message, e.g. "o.normalizeMessage();"msg.normalize();// this is also a violation, instead using temporary variable it uses method chain.o.getMessage().normalize();// this is OK, a constructor call, not a method call.Instrument symbol = new Instrument();// as per rule 4, this method call is OK, because instance of Instrument is created locally.symbol.populate(); }
}
您可以看到,当我们获得Order类的内部并在该对象上调用方法时,便违反了delimiter的Law ,因为现在该方法知道Message类。 另一方面,调用Order对象的方法很好,因为它作为参数传递给该方法。 此图像很好地说明了遵循Demeter定律需要做什么。
让我们看看另一个违反Demeter法则的代码示例,它如何影响代码质量。
public class XMLUtils {public Country getFirstBookCategoryFromXML(XMLMessage xml) { return xml.getXML().getBooks().getBookArrary(0).getBookHeader().getBookCategory();}
}
现在,此代码取决于许多类,例如
XML消息
XML格式 书 书头 图书类别
这意味着此函数了解XMLMessage,XML,Book,BookHeader和BookCategory。 它知道XML具有
Book,依次具有BookHeader和内部具有BookCategory,这是很多信息。 如果此链接方法调用中的任何中间类或访问器方法发生更改,则此代码将中断。 此代码高度耦合且脆弱。 最好将查找内部数据的责任放入拥有它的对象中。 如果仔细观察,应该只调用getXML()方法,因为它的方法来自XMLMessage类,该方法作为参数传递给方法。 不应将所有这些代码都放入XMLUtils中,而应该放在BookUtils或类似的东西上,它们仍然可以遵循Demeter的定律并可以返回所需的信息。
翻译自: https://www.javacodegeeks.com/2014/06/law-of-demeter-in-java-principle-of-least-knowledge-real-life-example.html