迪米特法则(Law of Demeter或简写LOD)又叫最少知识原则(LeastKnowledge Principle或简写(LKP),也就是说,一个对象应当对其他对象有尽可能少的了解。其他描述:
只与你直接的朋友通信,不要跟”陌生人“说话。每个软件单位对其它的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。
迪米特法则与设计模式:
Facade(外观) 模式、Mediator(中介者)模式
(1) 不要和”陌生人“说话,英文定义为:Do can't talk to strangers.
(2)只与你的直接朋友通信。英文定义为:Talk only to your immediate friends.
(3)每个软件单位对其他的单位都只有最少的知识,而且局限于那些与基本单位密切相关的软件单位。英文定义为:Each unit should have only limited knowledge about other units "closely" related to the current unit.
迪米特法则首先强调的前提是在类的结构设计上,每个类都应当尽量降低成员的访问权限,即一个类包装好自己的private状态,不要让别类知道的字段或行为就不要公开。需要公开的字段通常就用属性来体现。
面向对象的设计原则和面向对象的三大特性本就不是矛盾的。迪米特法则其根本思想是强调了在类之间的松耦合。如一天去一家公司,IT部的同事都不认识,你只要打个电话给IT叫IT部来修电脑即可,不需要认识IT里的所有同事。由于IT部类似于抽象的类或接口,哪怕该部门换了新人,你仍然可以联系IT部的新同事来修电脑。从而避免了”人际关系“办事的情况发生。
在程序设计时,类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会对有关系的类造成影响。即信息的隐藏促进了代码的复用。
例子:
使民无知:《老子》第三章曰:”是圣人之治,虚其心,实其腹,弱其志,常使民无知无欲。“使被”统治的对象“愚昧”化,处于“无知”的状态,可以使“统治”的成本降低。所谓“最小知识”原则,实际上便是老子的“使民无知”的统治之术。
不相往来:《老子》云:“小国寡民......邻国相望,鸡犬之声相闻,民至老死,不相往来。”将被统治的对象隔离开来,是他们没有直接的通信,可以达到分化瓦解,继而分而治之的效果。迪米特法则与老子的“小国寡民”的统治之术不谋而合。
在迪米特法则中,对于一个对象,其朋友包括以下几类:
(1)当前对象本身
(2)以参数形式传入当前对象方法中的对象
(3)当前对象的成员对象
(4)如果当前对象的成员对象是一个集合,那么集合中的元素也都是朋友;
(5)当前对象创建的对象。
任何一个对象满足上面的条件之一,就是当前对象的朋友,否则就是陌生人。
迪米特法则来自于1987年秋美国东北大学(Northeastern University)一个名为“Demeter”的研究项目
简单的说,迪米特法则就是指一个软件实体应当尽可能少的与其他实体发生相互作用。这样当一个模块修改时,就会尽量少的影响其他的模块,扩展会相对容易,这是对软件实体之间通信的限制,要求限制软件实体之间通信的宽度和深度。
狭义的迪米特法则:可以降低类之间的耦合,但是会在系统中增加大量的小方法并散落在系统的各个角落,它可以使一个系统的局部设计简化,因为每个局部都不会和远离的对象有直接的关联,但也会造成系统的不同模块之间的通信效率降低,使得系统的不同模块不容易协调。在狭义的迪米特法则中,如果两个类之间不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,如果其中一个类需要调用另一个类的某个方法的话,可以通过第三者转发这个调用。
广义的迪米特法则:指对对象之间的信息流量、流向以及信息的影响的控制,主要是对信息隐藏的控制。信息的隐藏可以使各个子系统之间脱耦,从而允许它们独立地被开发、优化、使用和修改,同时可以促进软件的复用,由于每个模块都不依赖于其他的模块存在,因此每个模块都可以独立的在其它地方使用。一个系统的规模越大,信息的隐藏就越重要,而信息的隐藏重要性也就越明显。
迪米特法则的主要用途就是控制信息的过载:
在类的划分上,应当尽量创建松耦合的类,类之间耦合度越低,就越有利于复用,一个处在松耦合的类一旦被修改,不会对关联的类造成太大的波及;在类的结构设计上,每个类都应当尽量降低其成员变量和成员函数的访问权限;
在类的设计上,只要有可能,一个类应当设计成不变类;
在对其他类的引用上,一个对象对其他对象的引用应当降到最低。