迪米特法则
定义:
一个对象应该对其他对象有最少的了解。
迪米特法则的要求
1.只和直接的朋友交流
什么是朋友?
每个对象必然都会与其他对象有耦合关系,两个对象之间的耦合就是朋友关系。这种关系的类型有组合,聚合,依赖。但是迪米特法则要求,只和直接朋友交流。
实例:
老师让体育委员清点班上的女生的人数。
public class Teacher {
public void commond(GroupLeader groupLeader) {
List<Girl> girlList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
girlList.add(new Girl());
}
groupLeader.countGirls(girlList);
}
}
public class GroupLeader {
public void countGirls(List<Girl> girlList){
System.out.println("女生的数量是:"+girlList.size());
}
}
//只要这个对象,不要有具体的实现
public class Girl {
}
public class Client {
public static void main(String[] args) {
Teacher teacher = new Teacher();
teacher.commond(new GroupLeader());
}
}
什么是朋友类?
就是出现在成员变量,或者方法的输入输出参数中的类才叫朋友类。而这里,Girl类和Teacher类不是朋友类关系,因为它没有出现在Teacher类的方法参数或者返回类型,或者成员变量中。它是局部变量,所以它和Teacher不是朋友类关系。
根据这里的分析,发现违背了迪米特法则,那修改这个类。
public class Teacher {
public void commond(GroupLeader groupLeader) {
groupLeader.countGirls();
}
}
public class GroupLeader {
private List<Girl> girls;
public GroupLeader(List<Girl> girlList){
this.girls = girlList;
}
public void countGirls(){
System.out.println("女生的数量是:"+girls.size());
}
}
public class Client {
public static void main(String[] args) {
Teacher teacher = new Teacher();
List<Girl> girlList = new ArrayList<>();
for (int i = 0; i < 20; i++) {
girlList.add(new Girl());
}
teacher.commond(new GroupLeader(girlList));
}
}
这样修改后,发现Teacher和GroupLeader是朋友类,GroupLeader和Girl是朋友类。这也符合业务逻辑,同时也符合迪米特法则。
2.朋友间也要保持距离
迪米特法则:即使是朋友类之间,也不能无话不说,无所不知。
实例:
假如我们要安装一个软件到PC端,安装过程也有一个步骤。
public class Wizard {
private Random random = new Random();
public int first() {
System.out.println("执行第一步安装");
return random.nextInt(100);
}
public int second() {
System.out.println("执行第二步安装");
return random.nextInt(100);
}
public int third() {
System.out.println("执行第三步安装");
return random.nextInt(100);
}
}
public class InstallSoftware{
public void install(Wizard wizard) {
int first = wizard.first();
if (first > 50) {
int second = wizard.second();
if (second > 50) {
int third = wizard.third();
if (third > 50) {
wizard.first();
}
}
}
}
}
上面的程序,是否有问题?
肯定有,试想如果把first方法的返回值改为boolean,那么InstallSoftware类也要跟着改变。这两个类的耦合关系太牢固,这样对修改增加了极大的风险,违背了迪米特法则。
修改:
public class Wizard {
private Random random = new Random();
private int first() {
System.out.println("执行第一步安装");
return random.nextInt(100);
}
private int second() {
System.out.println("执行第二步安装");
return random.nextInt(100);
}
private int third() {
System.out.println("执行第三步安装");
return random.nextInt(100);
}
public void installWizard(){
int first = this.first();
if (first > 50) {
int second = this.second();
if (second > 50) {
int third = this.third();
if (third > 50) {
this.first();
}
}
}
}
}
public class InstallSoftware{
public void install(Wizard wizard) {
wizard.installWizard();
}
}
把安装过程的三个方法,改为private修饰,提供一个public的安装方法。这样解耦过后,当某个方法修改时,就变得容易许多,而InstallSoftware类可以没有任何改变。
迪米特法则第二条,朋友间也要保持距离。
自己的就是自己的
如果一个方法放在本类中,既不增加类间关系,也不对本类产生负面影响,那就放在本类中。
谨慎使用Serializable
总结:
迪米特法则满足以上4点:
1.只和朋友交流
一个方法尽量不引入类中不存在的对象
2.朋友间保持距离
尽量少使用public公开信息
3.自己的就是自己的
如果一个方法既不产生类间关系,又不对本类产生负面影响,那就放在本类中
4.谨慎使用Serializable