设计原则之迪米特法则

迪米特法则

定义:
一个对象应该对其他对象有最少的了解。

迪米特法则的要求

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值