北风设计模式课程---最少知识原则(Least Knowledge Principle)

一、总结

一句话总结:

最少知识原则(Least Knowledge Principle),或者称迪米特法则(Law of Demeter):只和自己直接的 "朋友" 交谈。

1、最少知识原则 的好处是什么?

更好的信息隐藏:It leads to better information hiding.
更少的信息重载:It leads to less information overload.

2、最少知识原则 的 “ 只和自己直接的 '朋友' 交谈 ” 具体指(注意)什么?

方法返回的对象的方法:对象应尽可能地避免调用由另一个方法返回的对象的方法

3、如下代码的缺点是什么?

|||-begin

public Emailer(Server server) {…} // taking a server in the constructor
public void sendSupportEmail(String message, String toAddress) {
EmailSystem emailSystem = server.getEmailSystem();
String fromAddress = emailSystem.getFromAddress();
emailSystem.getSenderSubsystem().send(fromAddress, toAddress, message);
}

|||-end

1、复杂而且看起来不必要:Emailer 与多个它可能不是真的需要的 API 进行交互,例如 EmailSystem。
2、依赖太多:依赖于 Server 和 EmailSystem 的内部结构,如果两者之一进行了修改,则 Emailer 有可能被破坏。
3、不能重用:任何其他的 Server 实现也必须包含一个能返回 EmailSystem 的 API。

4、应用最少知识原则优点和缺点?

优点:降低耦合:遵守 Law of Demeter 将降低模块间的耦合,提升了软件的可维护性和可重用性。
缺点:提升复杂度:应用 Law of Demeter 可能会导致不得不在类中设计出很多用于中转的包装方法(Wrapper Method),这会提升类设计的复杂度。

二、最少知识原则(Least Knowledge Principle)

转自或参考:最少知识原则(Least Knowledge Principle)
https://www.cnblogs.com/gaochundong/p/least_knowledge_principle.html">最少知识原则(Least Knowledge Principle)

 

最少知识原则(Least Knowledge Principle),或者称迪米特法则(Law of Demeter),是一种面向对象程序设计的指导原则,它描述了一种保持代码松耦合的策略。其可简单的归纳为:

Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.

每个单元对其他单元只拥有有限的知识,只了解与当前单元紧密联系的单元;

再简洁些:

Each unit should only talk to its friends; don't talk to strangers.

每个单元只能和它的 "朋友" 交谈,不能和 "陌生人" 交谈;

更简洁些:

Only talk to your immediate friends.

只和自己直接的 "朋友" 交谈。

应用到面向对象的程序设计中时,可描述为 "类应该与其协作类进行交互但无需了解它们的内部结构"。

A class should interact directly with its collaborators and be shielded from understanding their internal structure.

迪米特法则(Law of Demeter)Northeastern UniversityIan Holland 在 1987 年提出,"Law of Demeter" 名称是来自当时正在进行的一项研究 "The Demeter Project"。

Demeter = Greek Goddess of Agriculture; grow software in small steps.

在 2004 年,Karl Lieberherr 在其论文 "Controlling the Complexity of Software Designs" 中将 LoD 的定义由 "Only talk to your friends" 改进为:

Only talk to your friends who share your concerns.

改进后的原则称为 LoDC(Law of Demeter for Concerns),它为软件设计带来了两个主要的益处:

It leads to better information hiding.

It leads to less information overload.

即,更好的信息隐藏和更少的信息重载。LoDC 原则在面向方面的软件开发(AOSD:Aspect-Oriented Software Development)中有着良好的应用。

最少知识原则在面向对象编程中的应用

在 "Law of Demeter" 应用于面向对象编程中时,可以简称为 "LoD-F:Law of Demeter for Functions/Methods"。

对于对象 O 中的一个方法 m ,m 方法仅能访问如下这些类型的对象:

  1. O 对象自身;
  2. m 方法的参数对象;
  3. 任何在 m 方法内创建的对象;
  4. O 对象直接依赖的对象;

具体点儿就是,对象应尽可能地避免调用由另一个方法返回的对象的方法。

现代面向对象程序设计语言通常使用 "." 作为访问标识,LoD 可以被简化为 "仅使用一个点(use only one dot)"。也就是说,代码 a.b.Method() 违反了 LoD,而 a.Method() 则符合 LoD。打个比方,人可以命令一条狗行走,但是不应该直接指挥狗的腿行走,应该由狗去指挥它的腿行走。

你是否见过类似下面这样儿的代码?

 public Emailer(Server server) {…} // taking a server in the constructor
public void sendSupportEmail(String message, String toAddress) {
EmailSystem emailSystem = server.getEmailSystem();
String fromAddress = emailSystem.getFromAddress();
emailSystem.getSenderSubsystem().send(fromAddress, toAddress, message);
}

上面这个设计有几点问题:

  1. 复杂而且看起来不必要。Emailer 与多个它可能不是真的需要的 API 进行交互,例如 EmailSystem。
  2. 依赖于 Server 和 EmailSystem 的内部结构,如果两者之一进行了修改,则 Emailer 有可能被破坏。
  3. 不能重用。任何其他的 Server 实现也必须包含一个能返回 EmailSystem 的 API。

除了上面这几个问题之外,还有一个问题是这段代码是可测试的吗?你可能会说肯定可测啊,因为这个类使用了依赖注入(Dependency Injection),我们可以模拟 Server、EmailSystem 和 Sender 类。但真正的问题是,除了多出了这些模拟代码,任何对 API 的修改都将破坏所有的测试用例,使得设计和测试都变得非常脆弱。

解决上述问题的办法就是应用最少知识原则,仅通过构造函数注入直接依赖的对象。Emailer 无需了解是否 Server 类包含了一个 EmailSystem,也不知道 EmailSystem 包含了一个 Sender。

 public Emailer(Sender sender, String fromAddress) {…}
public void sendSupportEmail(String message, String toAddress) {
sender.send(fromAddress, toAddress, message);
}

这个设计较为合理些。现在 Emailer 不再依赖 Server 和 EmailSystem,而是通过构造函数得到了所有的依赖项。同时 Emailer 也变得更容易理解,因为所有与其交互的对象都显式的呈现出来。

Emailer 与 Server 和 EmailSystem 也达到了解耦合的效果。Emailer 不再需要了解 Server 和 EmailSystem 的内部结构,任何对 Server 和 EmailSystem 的修改都不再会影响 Emailer。

而且,Emailer 的变得更易被复用。如果切换到另外一个环境中时,仅需实现一个不同的 Sender 即可。

对于测试而言,现在我们仅需模拟 Sender 依赖即可。

应用最少知识原则优点和缺点

优点:遵守 Law of Demeter 将降低模块间的耦合,提升了软件的可维护性和可重用性。

缺点:应用 Law of Demeter 可能会导致不得不在类中设计出很多用于中转的包装方法(Wrapper Method),这会提升类设计的复杂度。

面向对象设计的原则

参考资料

北风设计模式课程---最少知识原则(Least Knowledge Principle)的更多相关文章

  1. 北风设计模式课程---接口分离原则(Interface Segregation Principle)

    北风设计模式课程---接口分离原则(Interface Segregation Principle) 一.总结 一句话总结: 接口分离原则描述为 "客户类不应被强迫依赖那些它们不需要的接口& ...

  2. 北风设计模式课程---里氏替换原则(Liskov Substitution Principle)

    北风设计模式课程---里氏替换原则(Liskov Substitution Principle) 一.总结 一句话总结: 当衍生类能够完全替代它们的基类时:(Liskov Substitution P ...

  3. 北风设计模式课程---依赖倒置原则(Dependency Inversion Principle)

    北风设计模式课程---依赖倒置原则(Dependency Inversion Principle) 一.总结 一句话总结: 面向对象技术的根基:依赖倒置原则(Dependency Inversion ...

  4. 北风设计模式课程---单一职责原则(Single Responsibility Principle)

    北风设计模式课程---单一职责原则(Single Responsibility Principle) 一.总结 一句话总结: 一个类应该有且只有一个变化的原因:单一职责原则(SRP:Single Re ...

  5. 北风设计模式课程---开放封闭原则(Open Closed Principle)

    北风设计模式课程---开放封闭原则(Open Closed Principle) 一.总结 一句话总结: 抽象是开放封闭原则的关键. 1."所有的成员变量都应该设置为私有(Private)& ...

  6. 最少知识原则(Least Knowledge Principle)

    最少知识原则(Least Knowledge Principle),或者称迪米特法则(Law of Demeter),是一种面向对象程序设计的指导原则,它描述了一种保持代码松耦合的策略.其可简单的归纳 ...

  7. 设计模式之迪米特原则(LOD)(最少知识原则)

    来源:迪米特法则(LoD)最初是用来作为面向对象的系统设计风格的一种法则,是很多著名系统,如火星登陆软件系统.木星的欧罗巴卫星轨道飞船的软件系统的指导设计原则. 迪米特法则(LoD)又可分为两种:狭义 ...

  8. 设计模式值六大原则——迪米特法则(LoD)也称为最少知识原则(LKP)。

    定义: 迪米特法则(Law of Demeter,LoD)也称为最少知识原则(Least Knowledge Principle,LKP). 一个对象应该对其他对象有最少的了解.通俗地讲,一个类应该对 ...

  9. [Python设计模式] 第11章 迪米特法则——最少知识原则

    github地址:https://github.com/cheesezh/python_design_patterns 迪米特法则 迪米特法则(LoD),也叫最少知识原则,如果两个类不必彼此直接通信, ...

随机推荐

  1. 部署CM集群首次运行报错:Formatting the name directories of the current NameNode.

    1. 报错提示 Formatting the name directories of the current NameNode. If the name directories are not emp ...

  2. Luogu P1315 [NOIP2012]观光公交

    题目 每次把加速器用在可以是答案减少最多的地方就即可.(这不是废话吗?) 具体而言,我们处理出: \(sum_i\)到\(i\)为止下车人数之和. \(t_i\)在\(i\)最晚的上车的人的上车时间. ...

  3. Ubantu上安装Redis

    Ubantu上安装Redis:Redis(Remote Dictionary Server):远程字典服务器,简称REDIS;Redis数据库产品用C语言编写而成,开源.少量数据存储.高速读写访问,是 ...

  4. Eclipse删除已安装插件

    环境:(Windows) Eclipse 1.点击菜单"Help",选择"Install New Software",在弹出的对话框中选择"alrea ...

  5. 计算机系统结构总结_Branch prediction

    Textbook:<计算机组成与设计——硬件/软件接口>  HI<计算机体系结构——量化研究方法>          QR Branch Prediction 对于下面的指令: ...

  6. Response笔记

    # 今日内容          1. HTTP协议:响应消息     2. Response对象     3. ServletContext对象 ## HTTP协议:     1. 请求消息:客户端发 ...

  7. 自定义ajax函数(仿照jQuery)

    AJAX介绍 AJAX = 异步 JavaScript 和 XML. 全称:Asynchronous Javascript And XML: AJAX 是一种用于创建快速动态网页的技术. 通过在后台与 ...

  8. Linux--用户与用户组--03

    用户管理: 1.useradd 创建用户 -c 指定用户描述 -d 指定家目录 -g 指定主组 -G 指定附加组 附加组可以有多个 -s 指定shell程序 特殊的/sbin/nologin--> ...

  9. Zabbix--06主动模式和被动模式、低级自动发现、性能优化、

    目录 一. Zabbix主动模式和被动模式 1.克隆模版 2.修改克隆后的模版为主动模式 3.修改监控主机关联的模版为主动模式 4.修改客户端配置文件并重启 5.查看最新数据 二.Zabbix低级自动 ...

  10. HTML5初识

    HTML:超文本标记语言 HTML文档树结构 标签:有一对<>组成的,标签不区分大小写,大多数都是成对出现,有开始标签和结束标签,但也有单个出现的自闭和标签 标签属性:以键值对放在标签中, ...