波动拳式代码优化问题(二)、混合型

上一篇我们介绍了简单的波动拳式代码的优化,在实际业务开发的过程中,我们往往碰到的问题比上面的还要复杂。在各个条件中穿插着循环、判断等等。接下来我们来谈谈这一类代码的优化,请看下面的例子,我们有这样三类对象:

    老师————>班级————>学生
        1:n 1:n

一个老师任教多个年级的多个班级,一个班级有多名学生。来看下代码:

class Teacher {

    private int teachId;
    /**
     * 编号
     * 
     */
    private String classNo;
    /**
     * 名称
     * 
     */
    private String teachName;
    /**
     * 科目
     * 
     */
    private String subject;
    /**
     * 生日
     * 
     */
    private String birthDay;
    /**
     * 任教班级
     */
    private List<Classes> classList;
    ......
}
class Classes {

    private int classId;
    /**
     * 编号
     * 
     */
    private String classNo;
    /**
     * 名称
     * 
     */
    private String className;
    /**
     * 年级
     */
    private int grade;
    /**
     * 学生
     */
    private List<Student> studentList;
    ......
}
class Student {

    private int id;
    /**
     * 编号
     * 
     */
    private String studentNo;
    /**
     * 姓名
     * 
     */
    private String studentName;
    /**
     * 性别
     * 
     */
    private String gender;

    /**
     * 生日
     * 
     */
    private String birthDay;
    ......
}

我们现在有这样一个需求:我们想找出任教八年级数学的老师以及和这些老师具有相同生日的男性学生。一般的思路是这样的:

    先找出任教数学的老师;
    再找出这些任教九年级的班级
    再找出这些班级的男同学;
    最后比较老师和学生的生日
private void filter() {
        Map<Integer,Integer> relateMap = new HashMap<>(16);
        List<Teacher> teacherList = new ArrayList<Teacher>();
        for (Teacher teacher : teacherList) {
            if (teacher.getSubject().equals("math")) {
                List<Classes> classesList = teacher.getClassList();
                for (Classes classes : classesList) {
                    if (classes.getGrade() == 8) {
                        List<Student> studentList = classes.getStudentList();
                        for (Student student : studentList) {
                            if (student.getGender().equals("male")) {
                                if (student.getBirthDay().equals(teacher.getBirthDay())) {
                                    relateMap.put(student.getId(),teacher.getTeachId());
                                } 
                            }
                        }
                    }
                }
            }
        }
    }

我们可以看到,这是典型的波动拳式代码,谜一样的缩进。那怎么样优化呢?这时候,传统的语法是不能解决的,我们需要借助一些特殊的语法糖。譬如,我们使用Java的流式api。

        teacherList.stream().filter(t -> t.getSubject().equals("math")).forEach(teacher -> {
            teacher.getClassList().stream().filter(c -> c.getGrade() == 8).forEach(classes -> {
                classes.getStudentList().stream().filter(stu -> stu.getGender().equals("male")).forEach(student -> {
                    if (student.getBirthDay().equals(teacher.getBirthDay())) {
                        relateMap.put(student.getId(), teacher.getTeachId());
                    }
                });
            });
        });

看一下,是不是简洁了很多。有的小伙伴也许会说,这样写好像和之前差不多。其实不然,通过这样的改进,我们的逻辑更加清晰,更易于维护,将来扩展起来也更方便。
再比如出现的代码在混合型的基础上,每个条件分支又嵌套多层,这种情况在基于上面的优化前提下就比较好优化了。结合上一篇的介绍,我们可以按照模板套出来。

总结

在实际开发过程中,希望小伙伴们不能只为快速了实现业务功能,而乱了章法。这都是欠下的债,越往后债越背越多。工业生产强调的是团队协作,代码写出来是给人看的,要易于阅读,易于维护。总之,仁者见仁智者见智,这些还是需要大家自己去思考思考。

发表评论

邮箱地址不会被公开。 必填项已用*标注