软件设计模式原则(一)迪米特法则

开一个小专题------详细总结一下软件设计模式原则,这部分在《软计》和《java设计模式》中算是很重要的知识点,值得展开详细讲解一下~首先介绍的是【迪米特法则】


一.定义

迪米特法则又称为最少知识原则,其定义为:一个软件实体应当尽可能少的与其他实体发生相互作用。

  • 一个软件实体应当尽可能少的与其他实体发生相互作用,每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位
  • 迪米特法则的初衷在于降低类之间的耦合 。由于每个类尽量减少对其他类的依赖,因此,很容易使得系统的功能模块功能独立,相互之间不存在(或很少有)依赖关系。
  • 迪米特法则不希望类之间建立直接的联系。如果真的有需要建立联系,也希望能通过它的友元类来转达。因此,应用迪米特法则有可能造成的一个后果就是:系统中存在大量的中介类,这些类之所以存在完全是为了传递类之间的相互调用关系------这在一定程度上增加了系统的复杂度。

英文缩写为:LOD

如果两个软件实体无须直接通信,那么就不应当发生直接的相互调用,可以通过第三方转发该调用。其目的是降低类之间的耦合度,提高模块的相对独立性。

二.描述

如果一个系统满足迪米特法则,那么当其中一个软件实体发生变化时,就会尽量少的影响其他软件实体,扩展会相对容易,这是对软件实体之间通信的限制,迪米特法则要求限制软件实体之间通信的宽度和深度。

迪米特法则还有几种定义形式,包括:不要和"陌生人"说话、只与你的直接朋友通信 ,在迪米特法则中,对于一个对象,其朋友包括以下几类:

  • 当前对象本身(this)
  • 以参数形式传入到当前对象方法中的对象
  • 当前对象的成员对象
  • 如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友。
  • 当前对象创建的对象

任何一个对象,如果满足上面的条件之一,就是当前对象的"朋友",否则就是"陌生人"。在应用迪米特法则时,一个对象只能与直接朋友发生交互,不能与"陌生人"发生直接交互,好处在于降低耦合~

迪米特法则要求我们在设计系统时,应该尽量减少对象之间的交互,如果两个对象不必直接通信,那么这两个对象就不应该发生任何直接的相互作用,如果其中一个对象需要调用另外一个对象的某个方法时,可以通过【友元类】转发这个调用。

在迪米特法则运用到系统设计中时,要注意以下几点:

  • 在类的划分上,应该尽可能的创建松耦合的类,类之间的耦合度越低,复用率越高,一个松耦合的类发生修改不会对关联的类造成太大的影响。
  • 在类的结构设计上,每一个类都应当尽可能的降低其成员变量和成员方法的访问权限。
  • 在类的设计上,只要有可能,一个类型应当设计成不变类。
  • 在对其他类的引用上,一个对象对其他对象的引用应该降到最低。

三.案例

假设现在有一段时间,需要你学习某些内容,有代码如下:

java 复制代码
public class Time{
    public void studyMath() {
        // do something
    }
	public void studyChinese() {
        // do something
    }
	public void studyEnglish() {
        // do something
    }
    
    
    public void study() {
		studyEnglish();
		studyChinese();
		studyMath();
    }
}

public class Person {
    private Time time;
    
    public void Now() {
        // 学习什么都可以
		
        // 但是你发现Study类所有的方法都是公开的, 现在不知道该先学习哪个?
		time.studyMath();
		time.study();
        //也可以是
       time.studyMath();
	   time.studyEnglish();
    }
}

上述代码违背了迪米特原则,即对于对象time,此时不知道该学习什么------有多个方法可以调用~

(学一门,还是三门都学?)

如果改为如下的样式,则正确:

java 复制代码
public class Time{
    private void studyMath() {
        // do something
    }
	private void studyChinese() {
        // do something
    }
	private void studyEnglish() {
        // do something
    }
    
    
    public void study() {
		studyEnglish();
		studyChinese();
		studyMath();
    }
}

public class Person {
    private Time time;
    
    public void Now() {
        // 学习什么都可以
		
        // 但是你发现Study类所有的方法都是公开的, 现在不知道该先学习哪个?
		time.studyMath();
		time.study();
        //也可以是
       time.studyMath();
	   time.studyEnglish();
    }
}

总结就是一句话------尽可能降低现有的耦合,避免直接调用

相关推荐
小林学习编程2 小时前
Springboot考研信息平台
spring boot·后端·考研
LVerrrr5 小时前
Missashe考研日记—Day37-Day43
学习·考研
敲代码的 蜡笔小新17 小时前
【行为型之命令模式】游戏开发实战——Unity可撤销系统与高级输入管理的架构秘钥
unity·设计模式·架构·命令模式
m0_5557629017 小时前
D-Pointer(Pimpl)设计模式(指向实现的指针)
设计模式
小Mie不吃饭17 小时前
【23种设计模式】分类结构有哪些?
java·设计模式·设计规范
岑梓铭18 小时前
考研408《计算机组成原理》复习笔记,第二章(2)数值数据的表示(浮点数篇)
笔记·考研·408·计算机组成原理
meisongqing1 天前
【软件工程】机器学习多缺陷定位技术分析
人工智能·机器学习·软件工程·缺陷定位
君鼎1 天前
C++设计模式——单例模式
c++·单例模式·设计模式
敲代码的 蜡笔小新1 天前
【行为型之中介者模式】游戏开发实战——Unity复杂系统协调与通信架构的核心秘诀
unity·设计模式·c#·中介者模式
令狐前生1 天前
设计模式学习整理
学习·设计模式