设计模式笔记(五)设计六大原则之五--迪米特法则

也叫最少知道原则,Least Knowledge Principle

定义

一个对象应该对其他对象有最少的了解,通俗的讲,一个类应该对自己需要耦合或调用的类知道得最少,被耦合或调用的类的内部是多么复杂和我没有关系,我只要知道提供的public方法,就知道这么多,其他的都不关心。

四层含义

迪米特法则对类的低耦合提出了明确的要求

只和直接的朋友交流

两个对象之间的耦合成为朋友关系。
举个栗子:
老师向体育委员发命令,让他清点女生人数

/*
 * 老师类
 */
public class Teacher {
    //老师对学生发布命令,清点一下女生
    public void commond(GroupLeader groupLeader) {
        List<Girl> listGirl = new ArrayList<Girl>();
        //初始化女生
        for (int i = 0;i<20;i++) {
            listGirl.add(new Girl());

        }

        //告诉体育委员开始执行清查任务
        groupLeader.countGirls(listGirl);
    }
}
/*
 * 体育委员
 */
public class GroupLeader {
    //清查女生数量
    public void countGirls(List<Girl> listGirls) {
        System.out.println("女生的数量是:"+listGirls.size());
    }
}
/*
 * 女生
 */
public class Girl {

}
/*
 * 模拟老师命令体育委员清点女生人数场景
 */
public class Client {
    public static void main(String[] args) {
        Teacher teacher = new Teacher();
        //老师发布命令
        teacher.commond(new GroupLeader());
    }
}

发现Teacher的直接朋友是GroupLeader但是方法间却用了不是直接朋友的对象Girl,commond方法时teacher的方法,teacher却不知道自己与Girl有了依赖,这是不允许的。
现在要将这个依赖关系去掉。

/*
 * 老师类
 */
public class Teacher {
    //老师对学生发布命令,清点一下女生
    public void commond(GroupLeader groupLeader) {
        //告诉体育委员开始执行清查任务
        groupLeader.countGirls();
    }
}
/*
 * 体育委员
 */
public class GroupLeader {
    private List<Girl> listGirls ;
    public GroupLeader(List<Girl> listGirls ) {
        this.listGirls = listGirls;
    }
    //清查女生数量
    public void countGirls() {
        System.out.println("女生的数量是:"+this.listGirls.size());
    }
}
/*
 * 模拟老师命令体育委员清点女生人数场景
 */
public class Client {
    public static void main(String[] args) {
        //女生群体
        List<Girl> listGirls = new ArrayList<Girl>();
        Teacher teacher = new Teacher();
        //老师发布命令
        teacher.commond(new GroupLeader(listGirls));
    }
}

避开了Teacher类对陌生类的访问,降低了耦合性,提高了系统的健壮性。

朋友间是有距离的

类之间的耦合关系不能过于牢固,即使是朋友之间也不能无话不说。
举个栗子:

/*
 * 模拟安装软件动作,根据向导,第一个动作完毕下一个动作运行
 */
public class InstallSoftware {
    public void installWizard(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();
                }
            }
        }
    }
}
/*
 * 向导类
 */
public class Wizard {
    private Random rand = new Random(System.currentTimeMillis());

    //第一步
    public int first() {
        System.out.println("执行第一个方法");
        return rand.nextInt(100);
    }

    //第二步
    public int second() {
        System.out.println("执行第二个方法");
        return rand.nextInt(100);
    }

    //第三步
    public int third() {
        System.out.println("执行第三个方法");
        return rand.nextInt(100);
    }
}
/*
 * 场景类
 */
public class ClientForInstall {
    public static void main(String[] args) {
        InstallSoftware invoker = new InstallSoftware();
        invoker.installWizard(new Wizard());
    }
}

如果Wizard类中first方法返回值变了,那么InstallSoftware类也要发生变化,这样过于依赖了。
可以让public的方法减少,让private或者protected的方法多一些。
修改后:

/*
 * 模拟安装软件动作,根据向导,第一个动作完毕下一个动作运行
 */
public class InstallSoftware {
    public void installWizard(Wizard wizard) {
        wizard.installWizard();
    }
}

/*
 * 向导类
 */
public class Wizard {
    private Random rand = new Random(System.currentTimeMillis());

    //第一步
    private int first() {
        System.out.println("执行第一个方法");
        return rand.nextInt(100);
    }

    //第二步
    private int second() {
        System.out.println("执行第二个方法");
        return rand.nextInt(100);
    }

    //第三步
    private int third() {
        System.out.println("执行第三个方法");
        return rand.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();
                }
            }
        }
    }
}

是自己的就是自己的

如果一个方法放在本类中不增加类间关系,对本类不产生负面影响,那么就放在本类中。

谨慎使用Serializable

如果一个项目使用了远程方法调用,这个对象就必须实现Serializable接口,也就是需要把网络传输的对象序列化,否则就会出现异常。突然,客户端的VO修改了一个属性的访问权限,private变为public访问权限变大了,如果程序上没有变更,就会报序列化失败。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值