Java中的得墨meter耳定律–最少知识原理–实际示例

得墨meter耳定律(也称为最少知识定律)是一种编码原理,它表示模块不应该知道其操作的对象的内部细节。 如果代码依赖于特定对象的内部细节,则很有可能一旦该对象的内部发生更改,它就会被破坏。 由于封装是关于隐藏对象的内部细节并仅公开操作的,因此它还声明了Demeter定律 。 许多Java程序员都犯了一个错误,那就是它使用getter方法公开了对象的内部细节,而这正是知识最少的原则提醒您的地方。 在阅读一本必读的编程书 《罗伯特·C·马丁的清洁代码》时 ,我首先了解了这一原理。 除了本书教给你的许多好处之外, “最起码的原则”是一个原则,我至今仍然记得。 像许多不好的事情一样,由于以流利的风格编写的漂亮方法链,您将很容易违反德米特法则。 从表面上看,它看起来不错,但是一旦您想到了最少知识的原理,便开始看到真实的图画。 在本文中,我们将看到Demeter定律的正式定义,并探索违反该原理的代码段。

根据Demeter定律,对象O的方法M应该仅调用以下类型的方法:

  1. 对象O本身的方法
  2. 作为参数传递的Object方法
  3. 对象的方法,保存在实例变量中
  4. 在方法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() method
        Message 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定律需要做什么。

Java中的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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值