迪米特法则(Law of Demeter)

目录

 

1、基本介绍

2、应用实例

2.1、需求

2.2、传统方式实现

2.2.1、类图

2.2.2、代码

2.2.3、传统方式实现分析

2.3、遵循迪米特法则实现

2.3.1、类图

2.3.2、代码

2.3.3、迪米特法则实现分析

3、迪米特法则注意事项和细节


1、基本介绍

  • 迪米特法则(Demeter Principle)又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽可能将逻辑封装在类的内部。对外除了提供的public方法,不对外泄露任何信息;
  • 一个对象应该对其他对象保持最少的了解;
  • 类与类关系越密切,耦合度越大;
  • 迪米特法则还有个更简单的定义:只与直接的朋友通信;
  • 直接的朋友:每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式很多,依赖,关联,组合,聚合等。其中,我们称出现成员变量方法参数方法返回值中的类为直接的朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要局部变量的形式出现在类的内部

2、应用实例

2.1、需求

有校学生会成员和院学生会成员,现在需要编程打印所有学生会成员。

2.2、传统方式实现

2.2.1、类图

2.2.2、代码

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        CollegeManager collegeManager = new CollegeManager();
        SchoolManager schoolManager = new SchoolManager();
        schoolManager.printAllStudentCouncilMember(collegeManager);
    }
}

/**
 * 学校管理者
 */
class SchoolManager{

    /**
     * SchoolStudentCouncilMember是这个方法的返回值
     * 所以SchoolStudentCouncilMember是SchoolManager的直接朋友
     */
    public List<SchoolStudentCouncilMember> getAllSchoolStudentCouncilMember() {
        List<SchoolStudentCouncilMember> list;
        list = new ArrayList<>();
        for(int i=1;i<=10;i++){
            list.add(new SchoolStudentCouncilMember(i+""));
        }
        return list;
    }

    /**
     * 打印所有学生会成员
     */
    public void printAllStudentCouncilMember(CollegeManager collegeManager){
        System.out.println("---------校学生会----------");
        List<SchoolStudentCouncilMember> list1 = getAllSchoolStudentCouncilMember();
        for(SchoolStudentCouncilMember s : list1){
            System.out.println("校学生会:"+s.getId());
        }

        System.out.println("----------院学生会-----------");
        /**
         * CollegeStudentCouncilMember是局部变量
         * 所以CollegeStudentCouncilMember不是SchoolManager的直接朋友
         * 违反了迪米特法则
         */
        List<CollegeStudentCouncilMember> list2 = collegeManager.getAllCollegeStudentCouncilMember();
        for(CollegeStudentCouncilMember c : list2){
            System.out.println("院学生会:"+c.getId());
        }
    }
}

/**
 * 学院管理者
 */
class CollegeManager{
    public List<CollegeStudentCouncilMember> getAllCollegeStudentCouncilMember() {
        List<CollegeStudentCouncilMember> collegeStudentCouncilMemberList;
        collegeStudentCouncilMemberList = new ArrayList<>();
        for(int i=11;i<=20;i++){
            collegeStudentCouncilMemberList.add(new CollegeStudentCouncilMember(i+""));
        }
        return collegeStudentCouncilMemberList;
    }

}


/**
 * 校学生会成员
 */
class SchoolStudentCouncilMember{
    private String id;

    public SchoolStudentCouncilMember(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

/**
 * 院学生会成员
 */
class CollegeStudentCouncilMember{
    private String id;

    public CollegeStudentCouncilMember(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

运行结果:

2.2.3、传统方式实现分析

传统方式解决了问题,但是却违反了迪米特法则。

SchoolManager中的printAllStudentCouncilMember()方法中以局部变量的方式引用了CollegeStudentCouncilMember类,所以在这里CollegeStudentCouncilMember不是SchoolManager的直接朋友。

解决方式:将CollegeStudentCouncilMember变成SchoolManager的直接朋友,可以通过构造器传入、setter方法设置、参数传入等方式解决。

2.3、遵循迪米特法则实现

2.3.1、类图

说明:类图与原来的差别不大,只是将院学生会成员的打印细节封装到了院管理者内部,对外只暴露出一个printCollegeStudentCouncilMembel()方法。

2.3.2、代码

/**
 * 客户端
 */
public class Client {
    public static void main(String[] args) {
        CollegeManager collegeManager = new CollegeManager();
        SchoolManager schoolManager = new SchoolManager();
        schoolManager.printAllStudentCouncilMember(collegeManager);
    }
}

/**
 * 学校管理者
 */
class SchoolManager{

    /**
     * SchoolStudentCouncilMember是这个方法的返回值
     * 所以SchoolStudentCouncilMember是SchoolManager的直接朋友
     */
    public List<SchoolStudentCouncilMember> getAllSchoolStudentCouncilMember() {
        List<SchoolStudentCouncilMember> list;
        list = new ArrayList<>();
        for(int i=1;i<=10;i++){
            list.add(new SchoolStudentCouncilMember(i+""));
        }
        return list;
    }

    /**
     * 打印所有学生会成员
     */
    public void printAllStudentCouncilMember(CollegeManager collegeManager){
        System.out.println("---------校学生会----------");
        List<SchoolStudentCouncilMember> list1 = getAllSchoolStudentCouncilMember();
        for(SchoolStudentCouncilMember s : list1){
            System.out.println("校学生会:"+s.getId());
        }

        //打印院学生会
        collegeManager.printCollegeStudentCouncilMembel();
    }
}

/**
 * 学院管理者
 */
class CollegeManager{
    public List<CollegeStudentCouncilMember> getAllCollegeStudentCouncilMember() {
        List<CollegeStudentCouncilMember> collegeStudentCouncilMemberList;
        collegeStudentCouncilMemberList = new ArrayList<>();
        for(int i=11;i<=20;i++){
            collegeStudentCouncilMemberList.add(new CollegeStudentCouncilMember(i+""));
        }
        return collegeStudentCouncilMemberList;
    }

    /**
     * 打印院学生会
     */
    public void printCollegeStudentCouncilMembel(){
        List<CollegeStudentCouncilMember> list =  getAllCollegeStudentCouncilMember();
        System.out.println("----------院学生会-----------");
        for(CollegeStudentCouncilMember c : list){
            System.out.println("院学生会:"+c.getId());
        }
    }
}


/**
 * 校学生会成员
 */
class SchoolStudentCouncilMember{
    private String id;

    public SchoolStudentCouncilMember(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

/**
 * 院学生会成员
 */
class CollegeStudentCouncilMember{
    private String id;

    public CollegeStudentCouncilMember(String id) {
        this.id = id;
    }

    public String getId() {
        return id;
    }
}

运行结果与上面相同。

2.3.3、迪米特法则实现分析

将学院管理者与学校管理者两个类之间的耦合度降到了最低。学校管理者只需要调用打印院学生会成员的方法,而不需要知道其打印细节,这样提高了程序的可靠性。

3、迪米特法则注意事项和细节

  • 迪米特法则的核心是降低类之间的耦合
  • 但是注意:由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低类间(对象间)耦合关系,并不是要求完全没有依赖关系
发布了98 篇原创文章 · 获赞 26 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_42425970/article/details/97375005