zoukankan      html  css  js  c++  java
  • 设计模式六大原则之迪米特法则学习

    一、迪米特法则

      基本介绍

        (1)一个对象应该对其他对象保持最少的了解

        (2)类与类关系越密切,耦合度越大

        (3)迪米特法则(Demeter Priciple)又称最少知道原则,即一个类对自己依赖的类知道的越少越好。也就是说,对于被依赖的类不管多么复杂,都尽量将逻辑封装在类的内部。对外除了提供的public方法,不对外泄露任何消息

        (4)迪米特法则,还有更简单的定义:只与直接朋友通信

        (5)直接的朋友每个对象都会与其他对象有耦合关系,只要两个对象之间有耦合关系,我们就说这两个对象之间是朋友关系。耦合的方式越多,依赖、关联、组合、聚合等,其中,我们称出现成员变量,方法参数,方法返回值中的类为直接朋友,而出现在局部变量中的类不是直接的朋友。也就是说,陌生的类最好不要以局部变量的形式出现在类的内部。

      意义:降低类之间的耦合度

    二、案例演示

      场景:有一个学校,下属有各个学院和总部,现要求打印出学校总部员工ID和学院员工ID

      案例地址:https://github.com/Simple-Coder/design-pattern

    1、基础版代码实现

      定义4个类:Employee(学校总部员工类)、CollegeEmployee(学院的员工类)、CollegeManager(管理学院员工的管理类)、SchoolManager(学校管理类)

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * @ClassName: demeter01
     * @Description:
     * @Author: xiedong
     * @Date: 2020/3/21 21:17
     */
    public class demeter01 {
        public static void main(String[] args) {
            //创建了一个 SchoolManager 对象
            SchoolManager schoolManager = new SchoolManager();
            //输出学院的员工id 和  学校总部的员工信息
            schoolManager.printAllEmployee(new CollegeManager());
        }
    }
    
    //学校总部员工类
    class Employee {
        private String id;
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getId() {
            return id;
        }
    }
    
    //学院的员工类
    class CollegeEmployee {
        private String id;
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getId() {
            return id;
        }
    }
    
    //管理学院员工的管理类
    class CollegeManager {
        //返回学院的所有员工
        public List<CollegeEmployee> getAllEmployee() {
            List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
            for (int i = 0; i < 10; i++) { //这里我们增加了10个员工到 list
                CollegeEmployee emp = new CollegeEmployee();
                emp.setId("学院员工id= " + i);
                list.add(emp);
            }
            return list;
        }
    }
    
    //学校管理类
    class SchoolManager {
        //返回学校总部的员工
        public List<Employee> getAllEmployee() {
            List<Employee> list = new ArrayList<Employee>();
            for (int i = 0; i < 5; i++) { //这里我们增加了5个员工到 list
                Employee emp = new Employee();
                emp.setId("学校总部员工id= " + i);
                list.add(emp);
            }
            return list;
        }
    
        //该方法完成输出学校总部和学院员工信息(id)
        void printAllEmployee(CollegeManager sub) {
            //获取到学院员工
            List<CollegeEmployee> list1 = sub.getAllEmployee();
            System.out.println("------------学院员工------------");
            for (CollegeEmployee e : list1) {
                System.out.println(e.getId());
            }
            //获取到学校总部员工
            List<Employee> list2 = this.getAllEmployee();
            System.out.println("------------学校总部员工------------");
            for (Employee e : list2) {
                System.out.println(e.getId());
            }
        }
    }
    View Code

    实现效果:

    虽然结果实现了,但我们对SchoolManager类进行分析如下:

    分析:SchoolManager类的直接朋友:Employee、CollegeManager;陌生朋友:CollegeEmployee这样违背了迪米特法则

    2、基于迪米特法则改进版

      改进思路

        ①前面设计的问题在于SchoolManager中,CollegeEmployee类不是SchoolManager的直接朋友

        ②依据迪米特法则,应该避免在类中出现这样非直接朋友关系的耦合(即将输出学院员工方法,封装到CollegeManager中,对外除了提供public方法,不对外泄露任何信息

    2.1改进版代码

    public class demeter02 {
        public static void main(String[] args) {
            System.out.println("~~~使用迪米特法则的改进~~~");
            //创建了一个 SchoolManager 对象
            SchoolManager schoolManager = new SchoolManager();
            //输出学院的员工id 和  学校总部的员工信息
            schoolManager.printAllEmployee(new CollegeManager());
        }
    }
    
    //学校总部员工类
    class Employee {
        private String id;
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getId() {
            return id;
        }
    }
    
    
    //学院的员工类
    class CollegeEmployee {
        private String id;
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getId() {
            return id;
        }
    }
    
    
    //管理学院员工的管理类
    class CollegeManager {
        //返回学院的所有员工
        public List<CollegeEmployee> getAllEmployee() {
            List<CollegeEmployee> list = new ArrayList<CollegeEmployee>();
            for (int i = 0; i < 10; i++) { //这里我们增加了10个员工到 list
                CollegeEmployee emp = new CollegeEmployee();
                emp.setId("学院员工id= " + i);
                list.add(emp);
            }
            return list;
        }
    
        public void printEmployee() {
            //获取到学院员工
            List<CollegeEmployee> list1 = getAllEmployee();
            System.out.println("------------学院员工------------");
            for (CollegeEmployee e : list1) {
                System.out.println(e.getId());
            }
        }
    }
    
    //学校管理类
    class SchoolManager {
        //返回学校总部的员工
        public List<Employee> getAllEmployee() {
            List<Employee> list = new ArrayList<Employee>();
            for (int i = 0; i < 5; i++) { //这里我们增加了5个员工到 list
                Employee emp = new Employee();
                emp.setId("学校总部员工id= " + i);
                list.add(emp);
            }
            return list;
        }
    
        //该方法完成输出学校总部和学院员工信息(id)
        void printAllEmployee(CollegeManager sub) {
            //将输出学院的员工方法,封装到CollegeManager
            sub.printEmployee();
            //获取到学校总部员工
            List<Employee> list2 = this.getAllEmployee();
            System.out.println("------------学校总部员工------------");
            for (Employee e : list2) {
                System.out.println(e.getId());
            }
        }
    }
    View Code

    分析如下:

     依据迪米特法则就避免了在类中出现这样非直接朋友关系的耦合。

    三、总结

    1、迪米特法则的核心是降低类之间的耦合度

    2、由于每个类都减少了不必要的依赖,因此迪米特法则只是要求降低类间(对象间)耦合关系,并不是要求完全没有依赖关系。

  • 相关阅读:
    博客园
    未释放的已删除文件
    ssh连接缓慢
    剑指 Offer 38. 字符串的排列
    剑指 Offer 37. 序列化二叉树
    剑指 Offer 50. 第一个只出现一次的字符
    剑指 Offer 36. 二叉搜索树与双向链表
    剑指 Offer 35. 复杂链表的复制
    剑指 Offer 34. 二叉树中和为某一值的路径
    剑指 Offer 33. 二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/rmxd/p/12542480.html
Copyright © 2011-2022 走看看