设计原则之--迪米特法则

本文探讨了迪米特法则的核心思想及其在代码重构中的应用,通过实例展示了如何将不符合迪米特法则的系统重构为符合法则的系统,以降低耦合度和提高代码可维护性。
迪米特法则,又叫做最少知识原则(Least Knowledge Principle):如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果其中一个类需要调用另一个类的某一个方法的话,可以通过第三者转发这个调用。

迪米特法则,其根本思想,是强调了类之间的松耦合。

迪米特法则,另外几种表述方式:
只与你直接的朋友们通信(only talk to your immediate friends)
不要与“陌生人”说话(do not talk to strangers)
每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。

以下的条件成为“朋友”条件:
当前对象本身(this)
以参量形式传入到当前对象中的方法
当前对象的实例变量直接引用的对象
当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友
当前对象所创建的对象
如果满足上面条件之一,就是当前对象的“朋友”,负责就是“陌生人”

下面从代码重构的角度讨论怎样将一个不符合迪米特法则的系统,重构成为复合迪米特法则的系统。
系统中有3个类,Someone,Friend,Stranger,其中Someone与Friend是朋友,Friend与Stranger是朋友,系统结构图如下:其中Friend持有Stranger的引用,所以是朋友,在代码中可以看到Someone接受Friend作为参量,因此二者是朋友。

public class ASomeone {
	public void operation1(AFriend friend){
		System.out.println("通过Someone来调用Stranger");
		AStranger stranger = friend.provide();
		stranger.operation3();
	}
	public static void main(String[] args) {
		new ASomeone().operation1(new AFriend());
	}
}
public class AFriend {
	private AStranger stranger = new AStranger();
	public AStranger provide(){
		return stranger;
	}
	public void operation2(){
		
	}
}
public class AStranger {
	public void operation3(){
		System.out.println("调用了陌生人的函数");
	}
}
运行结果:
通过Someone来调用Stranger
调用了陌生人的函数

显然Someone的方法operation1方法不满足迪米特法则,因为这个方法引用了Stranger对象,而Stranger对象不是Someone的朋友。

改造之后的结构图:

与改造前相比,Someone与Stranger之间的联系已经没有了,Someone不需要知道Stranger的存在就可以做同样的事情。代码如下:
public class CSomeone {
	public void operation1(CFriend cfriend){
		cfriend.forward();
	}
	public static void main(String[] args) {
		new CSomeone().operation1(new CFriend());
	}
}
public class CFriend {
	private CStranger cstranger = new CStranger();
	public void operation2(){
		
	}
	public void forward(){
		System.out.println("通过Friend来调用Stranger");
		cstranger.operation3();
	}
}
public class CStranger {
	public void operation3(){
		System.out.println("调用了陌生人的函数");
	}
}
运行结果:
通过Friend来调用Stranger
调用了陌生人的函数

由于原来Friend类的forward方法所做的事情就是以前Someone要做的事情,使用了Stranger的operation3方法,而这种forward方法叫做转发方法。
由于使用了调用转发,使得调用的细节被隐藏在Friend内部,从而使得Someone与Stranger之间的直接联系被省略掉了。这样一来,使得系统内部的耦合度降低,在系统的某个类需要被修改时,仅仅会直接影响到这个类的“朋友”们,不会直接影响其余部分。

与依赖反转法则相辅助,引进一个抽象的AbstractStranger角色,让Someone依赖于这个角色,从而是Someone与Stranger的具体实现脱耦。如下图:

public abstract class AbstractStranger {
	public void operation3(){};
}
public class ASomeone {
	public void operation1(AFriend friend){
		System.out.println("通过Someone来调用Stranger");
		AStranger stranger = friend.provide();
		stranger.operation3();
	}
	public static void main(String[] args) {
		new ASomeone().operation1(new AFriend());
	}
}public class AFriend {
	private AStranger stranger = new AStranger();
	public AStranger provide(){
		return stranger;
	}
	public void operation2(){
		
	}
}public class AStranger {
	public void operation3(){
		System.out.println("调用了陌生人的函数");
	}
}
运行结果:
通过Someone来调用Stranger
调用了陌生人的函数





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值