IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> java设计模式6大设计原则之迪米特法则原则 -> 正文阅读

[Java知识库]java设计模式6大设计原则之迪米特法则原则

迪米特原则

1.1 迪米特法则定义

迪米特法则又称为最少知道原则,也就是说一个对象类对其他对象来说,知道的越少越好,两个类之间不要有过多的耦合关系,保持最少关联性。
迪米特法则有一句经典语录:只和朋友通信,不和陌生人说话。也就是说有关联的内要内聚,没有直接关系的类要低耦合。

2.1 模拟场景

通过模拟学生、老师、校长之间的关系来模拟迪米特法则。老师负责具体某一个学生的学习情况,而校长只会关系每个班级的总体成绩,不会具体过问某一个学生的具体成绩。
如果校长想要知道一个班级的总体成绩是直接找每个学生要再进行统计呢,还是应该向老师要呢?显然应该是直接向老师要一个班级的总体成绩。我们在实际开发,容易忽略这样的真实情况,开发出逻辑错误的程序。

2.2 违背原则方案

首先定义一个学生类,主要有学生姓名、考试排名、总分。

public class Student {
    private String name; //学生姓名
    private int rank;   //考试排名
    private double grade;   //总分

    public Student() {
    }

    public Student(String name, int rank, double grade) {
        this.name = name;
        this.rank = rank;
        this.grade = grade;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getRank() {
        return rank;
    }

    public void setRank(int rank) {
        this.rank = rank;
    }

    public double getGrade() {
        return grade;
    }

    public void setGrade(double grade) {
        this.grade = grade;
    }
}

之后再定义出老师类,在老师类中初始化学生信息,以及提供基本信息获取接口

public class Teacher {
    private String name;    //老师姓名
    private String clazz;   //班级
    private static List<Student> studentList; //学生人数

    public Teacher() {
    }

    public Teacher(String name, String clazz) {
        this.name = name;
        this.clazz = clazz;
    }

    static {
        studentList=new ArrayList<>();
        studentList.add(new Student("小明",10,450));
        studentList.add(new Student("花花",4,553));
        studentList.add(new Student("小明",18,354));
        studentList.add(new Student("小明",7,581));
        studentList.add(new Student("小明",20,300));
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public static List<Student> getStudentList() {
        return studentList;
    }

    public static void setStudentList(List<Student> studentList) {
        Teacher.studentList = studentList;
    }
}

在老师类中初始化了学生信息,同时提供了简单的接口。下面定义校长类,校长管理全局,并在校长类中获取学生人数、总分、平均分等。

public class Principal {
    private Teacher teacher = new Teacher("王丽", "5年级1班");

    //查询班级信息,总分、平均分、学生人数
    public Map<String, Object> queryClazzInfo(String clazzId) {
        //获取学生人数
        int stuCount = clazzStudentCount();
        //获取平均分
        double averageScore = clazzAverageScore();
        //获取总分
        double totalScore = clazzTotalScore();
        //组装对象
        Map<String, Object> map = new HashMap<>();
        map.put("老师", teacher.getName());
        map.put("班级", teacher.getClazz());
        map.put("人数", stuCount);
        map.put("平均分", averageScore);
        map.put("总分", totalScore);
        return map;
    }

    //获取学生人数
    private int clazzStudentCount() {
        return teacher.getStudentList().size();
    }

    //获取班级学生总分
    public double clazzTotalScore() {
        return teacher.getStudentList()
                .stream()
                .map(Student::getGrade).mapToDouble(Double::doubleValue).sum();
    }

    public double clazzAverageScore() {
        double sum = teacher.getStudentList()
                .stream()
                .map(Student::getGrade).mapToDouble(Double::doubleValue).sum();
        return sum / teacher.getStudentList().size();
    }
}

以上就是通过校长管理所有学生,老师只提供非常简单的信息。虽然可以查看到结果,但是违背了迪米特法则,因为校长需要了解每个学生的情况。如果所有班级类都让校长类进行统计,代码就会变得非常臃肿,也不易于扩展和维护。

2.3 迪米特法则改善代码

从以上实现方式我们发现,不该让校长直接管理学生,应该老师管理学生,校长管理老师。所以应该老师类通过学生信息查询服务。下面我们把校长要的信息交给老师类去处理。

public class Teacher {
    private String name;    //老师姓名
    private String clazz;   //班级
    private static List<Student> studentList; //学生人数

    public Teacher() {
    }

    public Teacher(String name, String clazz) {
        this.name = name;
        this.clazz = clazz;
    }

    static {
        studentList=new ArrayList<>();
        studentList.add(new Student("小明",10,450));
        studentList.add(new Student("花花",4,553));
        studentList.add(new Student("小明",18,354));
        studentList.add(new Student("小明",7,581));
        studentList.add(new Student("小明",20,300));
    }
    //获取学生人数
    public int clazzStudentCount() {
        return getStudentList().size();
    }

    //获取班级学生总分
    public double clazzTotalScore() {
        return getStudentList()
                .stream()
                .map(Student::getGrade)
                .mapToDouble(Double::doubleValue).sum();
    }
    //获取平均分
    public double clazzAverageScore() {
        double sum = getStudentList()
                .stream()
                .map(Student::getGrade)
                .mapToDouble(Double::doubleValue).sum();
        return sum / getStudentList().size();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public static List<Student> getStudentList() {
        return studentList;
    }

    public static void setStudentList(List<Student> studentList) {
        Teacher.studentList = studentList;
    }
}

使用迪米特法则后,将原来违背迪米特法则的服务接口交给老师类去处理。这样每一位老师都会提供对应的功能,校长类只需要调用即可,而不需要了解每一位学生的分数。

接来看校长类如何使用,如下所示:

public class Principal {
    private Teacher teacher = new Teacher("王丽", "5年级1班");

    //查询班级信息,总分、平均分、学生人数
    public Map<String, Object> queryClazzInfo(String clazzId) {
        //获取学生人数
        int stuCount = teacher.clazzStudentCount();
        //获取平均分
        double averageScore = teacher.clazzAverageScore();
        //获取总分
        double totalScore = teacher.clazzTotalScore();
        //组装对象
        Map<String, Object> map = new HashMap<>();
        map.put("老师", teacher.getName());
        map.put("班级", teacher.getClazz());
        map.put("人数", stuCount);
        map.put("平均分", averageScore);
        map.put("总分", totalScore);
        return map;
    }
}

校长类直接调用老师类服务接口即可,这样一来整个功能逻辑就非常清晰了。

下面验证程序结果:

public class Test {
    public static void main(String[] args) {
        Principal principal = new Principal();
        Map<String, Object> map = principal.queryClazzInfo("5年级1班");
        System.out.println("查询结果:"+map);
    }
}

查询结果:{总分=2238.0, 班级=5年级1, 老师=王丽, 人数=5, 平均分=447.6}

以上就是迪米特法则的基本使用。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-10-21 12:03:18  更:2021-10-21 12:05:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年10日历 -2024/10/29 6:20:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码