北风设计模式课程---最少知识原则(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. Redis在Windows环境配置多实例多端口运行

    Redis是一种跨平台NoSql内存数据库,这几年各大公司系统应用中非常多见,支持多种数据类型,可以持久化保存数据,很多公司直接拿来作为数据库使用. 相比于Memcached,Redis支持持久化保存 ...

  2. 线性表源码分享(c++),包含顺序表、单链表、循环链表、双向链表

    ---恢复内容开始--- 我是一个c++和数据结构的初学者,本文主要是把清华大学出版社的数据结构(用面向对象方法与c++语言描述)(第2版)这本书中第二章线性表的源码抄下来,在学习的过程中有助于加深印 ...

  3. golang 状态机

    package main import ( "errors" "fmt" "reflect" ) type State interface ...

  4. 利用中转输出表制作HijackDll

    [原创]利用中转输出表制作HijackDll(附工具源码)作 者: baixinye时 间: 2012-08-05,16:48:45链 接: http://bbs.pediy.com/showthre ...

  5. Qradar SIEM--查询利器 AQL

    对于 SIEM 平台来说,好用的查询方式非常重要.之前有体验基于 ELK 搭建的平台,在 kibana 上面是可以通过一些 filter 来做一些过滤并且是支持 lucene 的语法,包括一些简单的逻 ...

  6. express热更新nodemon,自启动项目

    一.说一下 每次修改文件,我们都需要重启服务器npm start,很麻烦,所以使用引入nodemon插件,解决这个问题,实现保存文件,即自启动刷新项目 二.直接开码 npm install nodem ...

  7. MongoDB的使用学习之(六)MongoDB的高级查询之条件操作符

    此文分为两点,主要是在第二点--java 语法,但是按顺序必须先把原生态的语法写出来 (还有一篇文章也是不错的:MongoDB高级查询用法大全(包含MongoDB命令语法和Java语法,其实就是我整理 ...

  8. 自定义UICollectionLayout

    #import "AppDelegate.h"#import "CircleLayout.h"#import "CollectionViewDataS ...

  9. linux下解压缩.tar.bz2到某目录下

    1\可先进入要解压的目的目录,然后使用tar命令 比如我要将桌面的a.tar.bz2解压到/var/b cd   /var/b tar   -xjf   /root/Desktop/a.tar.bz2 ...

  10. windows无法安装.net framework 3.5解决方法

    windows server 12r2 或 win10 安装.netframework 3.5方法: 一. 直接在“启用或关闭windows功能”中可以启用,需联网.但是经常会出错,可能安装过程中需要 ...