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…

记录6月28日的体验,自己现实的感触

2016年6月28日,是我自己要求的要去湖北的日子,可是现在,这个只能成为过去式,只能是提一提! 2016年5月17日,我在想,我要通宵加班,做好自己最好,最期待完成的3.0&#xff0…

lucene索引

1。lucene的索引尽量不要频繁而小量的编制,比如:用户每发一个贴子,就加入索引,那样对索引的结构和效率不利。 可以采用定时或者定量,批量处理索引的方式。 2。在批量处理的基础上,解决冲突的问题的方案之一…

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

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

合并两个有序数组,并输出中间值

示例1: nums1 [1,3] nums2 [2,4] output: (23) / 2 2.5 示例2: nums1 [2,5,7] nums2 [3,6] output:5 Python解决方案: def findMedianSortedArrays(self, nums1, nums2):""":type nums1: List[int]:type nums2: List[int…

Python中关于文件路径的简单操作 [转]

1: os.listdir(path) #path为目录 功能相当于在path目录下执行dir命令,返回为list类型 举例: print os.listdir(..) 输出: [a,b,c,d] 2: os.path.walk(path,visit,arg) path :是将要遍历的目录 visit &#xff1…

生产上完成TopN统计流程

背景 现有城市信息和产品信息两张表在MySQL中,另外有用户点击产品日志以文本形式存在hdfs上,现要求统计每个个城市区域下点击量前三的产品名,具体信息见下方。 mysql> show tables; --------------------------------- | Tables_in_d7 …

最大公因数和最小公倍数

一丶 最大公因数求法&#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>…

JPA 2.1实体图–第2部分:在运行时定义延迟/急切加载

这是我关于JPA 2.1实体图的第二篇文章。 第一篇文章描述了命名实体图的用法。 这些可用于定义在编译时将使用查找或查询方法获取的实体和/或属性的图形。 动态实体图以相同的方式但以动态方式这样做。 这意味着您可以在运行时使用EntityGraph API定义实体图。 如果您错过了第一…

HDU1166-敌兵布阵

http://acm.hdu.edu.cn/showproblem.php?pid1166 线段树第一题 #include<cstdio> #define lson l,m,rt<<1 #define rson m1,r,rt<<1|1 const int maxn55555; int sum[maxn<<2]; void PushUP(int rt) {sum[rt]sum[rt<<1]sum[rt<<1|1]; } …

js对象序列化为json字符串

网上找了找将js对象序列化为json字符串的方法。结果都不近人意&#xff0c;最后自己写了一个。 注意你得自己为Date增加toString()方法。 function Serialize(obj){switch(obj.constructor){case Object:var str "{";for(var o in obj){str o ":" Seri…

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;组件的第一个字母必须大写&…

Spring4:没有默认构造函数的基于CGLIB的代理类

在Spring中&#xff0c;如果要代理的目标对象的类未实现任何接口&#xff0c;则将创建基于CGLIB的代理。 在Spring 4之前&#xff0c;基于CGLIB的代理类需要默认的构造函数。 这不是CGLIB库的限制&#xff0c;而是Spring本身。 幸运的是&#xff0c;从Spring 4开始&#xff0c;…

linux里面i386 i686 i486 i586代表什么?是什么意思

URL:http://hi.baidu.com/software_one/blog/item/85c7ccedd70d6925acafd5e0.html 在linux里面&#xff0c;我们经常会遇到i386 i686 i486 I586 这些代码&#xff0c;例如查看内核版本&#xff1a; [rootlocalhost logs]# uname -a Linux localhost.localdomain 2.6.18-164.el5…

汇编语言學習

汇编语言 汇编语言(Assembly Language)是面向机器的程序设计语言.汇编语言是一种功能很强的程序设计语言,也是利用计算机所有硬件特性并能直接控制硬件的语言。汇编语言”作为一门语言&#xff0c;对应于高级语言的编译器&#xff0c;需要一个“汇编器”来把汇编语言原文件汇编…

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

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

DevStack方式安装queens版openstack

最近在学习openstack,在安装阶段就遇到了很多问题&#xff0c;特把安装过程记录如下&#xff0c;经笔者验证能正确安装openstack。 说明&#xff1a;安装后即为中文版。 2019/01/29: 安装环境&#xff1a; 宿主&#xff1a; Ubuntu 16.04 xenial Hypervisor: kvm 虚拟机&#x…

dev c++ 报错[Error] ld returned 1 exit status 的解决办法

我是个C语言的初学者&#xff0c;在使用dev c 编译器时&#xff0c;遇到一个情况&#xff1a;程序是正确的&#xff0c;能够正常的编译和运行&#xff0c;但是运行一次之后再次运行之时就出现了 报错[Error] ld returned 1 exit status&#xff0c;出现这个问题的原因是&#x…