北风设计模式课程---最少知识原则(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. (二)inlineCallbacks,同步方式写异步代码

    一. 上篇提到了用defered对象注册回调的方式,来处理异步操作,这样大家都知道,实际情况代码很难搞的.因为当业务逻辑复杂后,这边一个异步操作,我们注册一个回调,代码跳到A地方,A里面也有异步操作, ...

  2. docker下部署kafka集群(多个broker+多个zookeeper)

    网上关于kafka集群的搭建,基本是单个broker和单个zookeeper,测试研究的意义不大.于是折腾了下,终于把正宗的Kafka集群搭建出来了,在折腾中遇到了很多坑,后续有时间再专门整理份搭建问 ...

  3. oracle管理基础知识

    1.oracle的安装 win下 linux下 2.内存和后台进程=实例 为何将oracle做的如此复杂呢 1.内存: --提高查询速度 --提升处理数据的速度 2.后台进程 --为了完成特定的服务, ...

  4. 洛谷 - P1346 - 电车 - Dijkstra/01BFS

    https://www.luogu.org/problem/P1346 使用最短路之前居然忘记清空了. #include<bits/stdc++.h> using namespace st ...

  5. 04-Django-templates

    # 模板系统 - 模板:一组相同或者相似的页面,在需要个性化的地方进行留白,需要的时候只是用数据填充就可以使用 - 步骤: 1. 在settings中进行设置:TEMPLATES 2. 在tmeplt ...

  6. [七月挑选]windows上面的发音

    title: windows上面的发音 开始 love.vbs: CreateObject("SAPI.SpVoice").Speak "I love YOU" ...

  7. (架构)React Native 导出项目全局共用组件的模块

    自定义组件全局使用(类似如下) import { ReactNavComponent, Widget, Util } from 'rn-yunxi'; const { RegexpUtil, Stor ...

  8. mesg - 调节用户终端的写访问权

    总览 (SYNOPSIS) mesg [y|n] 描述 (DESCRIPTION) Mesg 控制 其他用户 对 你的终端 的 访问能力. 典型用途 是 允许 或 禁止 其他用户向 你的终端 输出 数 ...

  9. python并发编程中的多进程(代码实现)

    一.multipricessing模块的介绍 python中的多线程无法利用多核优势,如果想要充分的使用多核CPU资源,在python中大部分情况下需要用多线程,python提供了multiproce ...

  10. 十一、Boostrap-X-editable

    一.官网 http://vitalets.github.io/x-editable/index.html 二.实践 在jQuery中ajax配置项中的使用type与method的区别: type 和m ...