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() 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定律需要做什么。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363477.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

课后作业1

自我介绍 我叫张阔,我的爱好是旅行,游览世界的美好风光; 我的码云个人主页是:https://gitee.com/ZkTt0428; 我的第一个项目地址是:https://gitee.com/ZkTt0428/Frist; 目前代码量有10000行了&am…

针对新手的Java EE7和Maven项目-第4部分-定义Ear模块

从前面的部分恢复 第1部分 第2部分 第3部分 我们正在恢复第四部分,目前我们的简单项目有 Web Maven模块(战争) 一个ejb模块(ejb),其中包含我们的无状态会话bean(EJB 3.1) 第二…

最大公因数和最小公倍数

一丶 最大公因数求法&#xff1a;辗转相除法(也称欧几里得算法)原理: 二丶最小公倍数求法&#xff1a;两个整数的最小公倍数等于两整数之积除以最大公约数1 #include <iostream>2 3 using namespace std;4 5 //辗转相除法(欧几里得算法)6 7 int gcd(int a, int b)8 {9…

css实现div内一段文本的两端对齐

在一个固定宽度的div内&#xff0c;使得P标签内的文本两端对齐&#xff1a; text-align: justify;text-justify:inter-ideograph; <!DOCTYPE html><html lang"en"><head><meta charset"UTF-8"><title>justify</title>…

QT学习三 标准对话框 QMessageBox

QMessageBox内置了几种static方法,例如 QMessageBox::question() 返回值:StandardButton 参数:QWidget * 父窗口&#xff0c;标题名&#xff0c;内容&#xff0c;按钮 YES|NO,默认选中按钮) 示例: 1 #include "mainwindow.h"2 #include <QApplication>3 #incl…

react学习笔记2

1.build文件介绍 &#xff08;1&#xff09;react.js 是react的核心库 &#xff08;2&#xff09;react-dom.js 提供与DOM相关功能 &#xff08;3&#xff09;browser.js 是将JSX语法转为javascript语法 2.组件的继续学习 注意&#xff1a;组件的第一个字母必须大写&…

HOW-TO:带有MySQL的JEE应用程序中具有集群功能的Quartz Scheduler

Quartz Scheduler是Java世界中最流行的调度库之一。 过去&#xff0c;我主要在Spring应用程序中使用Quartz。 最近&#xff0c;我一直在研究将在云中部署的JBoss 7.1.1上运行的JEE 6应用程序中的调度。 我考虑的一种选择是Quartz Scheduler&#xff0c;因为它提供了与数据库的集…

C语言使用scanf()函数时,%c前面和后面分别加上空格后的结果

在使用scanf()读取输入的字符时&#xff0c;当转换说明为%c时&#xff0c;"%c"、" %c"、"%c " 这三种不同的写法&#xff0c;对数据读取的结果有什么影响吗&#xff0c;答案是肯定的&#xff0c;%c 加不加空格&#xff0c;空格在前还是在后&am…

Python -- 自动导入所需要的模块

try: import xlwtexcept ImportError as e:   import os   print(e)   os.system("pip install xlwt")转载于:https://www.cnblogs.com/xlx12138/p/10551894.html

借助Apache Hadoop大规模扩展Apache Solr实时实时索引

播客的第22集是与Patrick Hunt的谈话 我们讨论了Apache Solr&#xff08;上游&#xff09;中的新工作&#xff0c;使它可以在Apache Hadoop上工作。 Solr支持将其索引和事务日志文件写入和读取到HDFS分布式文件系统。 这不使用Hadoop Map-Reduce处理Solr数据&#xff0c;而是仅…

linux查看用户、创建用户、设置密码、修改用户、删除用户命令

查看用户 tail -1 /etc/passwd tail -1 /etc/shadow id alex echo 123 |passwd --stdin alex # 设置密码&#xff0c;不需要交互[rootlocalhost ~]# tail -l /etc/passwd rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS …

去除git版本控制

命令&#xff1a;find . -name ".git" | xargs rm –Rflinux $ find . -type d -iname __pycache__ -exec rm -rf {} \;转载于:https://www.cnblogs.com/gispathfinder/p/10555347.html

如何在Java中找到整数的质因数–因式分解

编程课程中的常见家庭作业/任务之一是关于Prime Factorization。 要求您编写一个程序以找到给定整数的素因子 。 一个数字的质数因子是将精确地除以给定数字的所有质数。 例如&#xff0c;35的素数因子分别是7和5&#xff0c;它们本身都是素数&#xff0c;并且精确地除以35。上…

Arduino Serial系列函数 有关print read 的总结

总结一下 在学习arduino srial函数时 的几个知识点&#xff1a; /*** 汇总一下Serial.print输出的一些情况&#xff0c;后面部分要和Serial.read配合使用&#xff1b;* 1. print 输出字符 和int数的结果&#xff0c;* 2. print 输出字符串和一连串的数字* 3. read 读取一个字符…

C#经典名著:《C#入门经典》(第4版)

博客园专题&#xff1a;http://book.cnblogs.com/zt/begin_csharp/ 作  者&#xff1a; &#xff08;美&#xff09;沃森&#xff08;Watson&#xff0c;K.&#xff09;&#xff0c;&#xff08;美&#xff09;内格尔&#xff08;Nagel&#xff0c;C.&#xff09; 等著&#…

您必须学习Java 8的函数式编程吗?

我最近一直在研究Java 8&#xff0c;并掌握了Manning出版的“ Java 8 In Action” 。 让我印象深刻的第一件事是Java 8的独特销售主张是函数式编程。 函数现在是一流的变量&#xff0c;您可以像int或String一样在代码中传递它们。 这是一个很大的变化。 近年来&#xff0c;功能…

巨蟒django之权限6: 权限控制表设计登录权限

1.权限控制表设计 内容 1. 什么是权限&#xff1f; 2. 为什么要有权限&#xff1f;不同用户拥有不同的功能 3. 在web开发中&#xff0c;什么是权限&#xff1f;url 代表 权限4. 开发一个权限的组件&#xff0c;为什么要开发组件&#xff1f;5. 表结构的设计# 第一版权限表 pe…

CSS制作镂空字体

1.效果图 2.html内容&#xff1a; <!doctype html><html lang"en"><head> <meta charset"UTF-8"> <title>Document</title></head><style> body{background: rgb(248,248,248);} span{font-size: 240px;…

为什么要在Java的Serializable类中使用SerialVersionUID

序列化和SerialVersionUID始终是许多Java开发人员的难题。 我经常会看到类似此SerialVersionUID的问题&#xff0c;或者如果不在我的Serializable类中声明SerialVersionUID会发生什么情况&#xff1f; 除了涉及到的复杂性和罕见的使用之外&#xff0c;这些问题的另一个原因是Ec…

SQL2005-使用openrowset 里读取excel文件

很多时候我们都知道使用.net代码去读取word,excel文档&#xff0c;但是我们如何使用sql句语里读取excel文件呢&#xff1a;SQL2005为我们提供了OPENROWSET来访问各种数据源&#xff1a;,当然我还是建议使用.net代码来读取这些文件。这里就不多说了。 我们先看一下官方的解释&am…