readme

Java面向对象程序设计-高级课程查询(一)

需求分析

我们在之前的项目中实现了CourseSearch类;该类保存了多个查询条件,并提供了成员方法isSatisfied()来检查课程对象是否满足查询条件。但是,当前的CourseSearch类只能按照逻辑"与"来设置条件。比如,用户可以设置条件A和条件B来查询课程。findCourse()方法能够返回同时满足这两个条件的课程。可是,有时用户可能希望给定两个条件,查询结果只需满足其中一个条件即可。我们称这种查询方式为按照逻辑"或"来查询。因此,我们将在本项目中开发一个高级课程搜索功能,允许用户任意使用逻辑"与"和逻辑"或"来组合多个条件。虽然java.util.function.Predicate类已支持了类似的功能,但是本项目作为一个学习项目,我们将使用组合模式来实现这个高级查询功能。

步骤一

首先,我们在com.littlewaterdrop.search包中声明一个新的公有接口SearchCriterion。它有一个公有方法isSatisfied()。该方法接受一个输入参数Course,返回一个boolean类型的结果。当输入参数满足查询条件时,返回true;当输入参数不满足查询条件时,返回false。

boolean isSatisfied(Course course);

步骤二

在第二步中,我们实现一个按照课程名字查询的条件。在com.littlewaterdrop.search包中,我们创建一个新类NameBasedCriterion,它实现了SearchCriterion接口。

NameBasedCriterion类声明了一个公有构造函数,接受一个待查询的名字。

NameBasedCriterion类还实现了isSatisfied()方法。当课程名称与构造函数传入的名称相同时,isSatisfied()方法返回true;否则,返回false。

我们再在com.littlewaterdrop.search包中创建一个新的公有类SearchCriterionFactory。它有一个公有静态方法newNameBasedCriterion()方法,根据输入参数name,创建一个NameBasedCriterion类对象。这个静态方法的原型如下所示。

public static NameBasedCriterion newNameBasedCriterion(String name);

步骤三

我们再实现一个按照逻辑"与"处理的组合查询条件。在com.littlewaterdrop.search包中创建一个新类CombineTwoCriteria,实现接口SearchCriterion。

CombineTwoCriteria类提供一个构造函数,接收两个SearchCriterion对象。CombineTwoCriteria类的isSatisfied()方法同时检查这两个SearchCriterion对象。只有当这两个对象都返回true时,CombineTwoCriteria类的isSatisfied()方法才返回true。否则返回false。

public class CombineTwoCriteria implements SearchCriterion {
    public CombineTwoCriteria(SearchCriterion a, SearchCriterion b) {
        ...
    }
}

在SearchCriterionFactory类中新增一个公有的静态方法,命名为newCombineTwoCriteria()。该方法接收两个SearchCriterion对象,返回一个新创建的CombineTwoCriteria对象。

public static CombineTwoCriteria newCombineTwoCriteria(SearchCriterion a, SearchCriterion b);

步骤四

在实现了逻辑"与"之后,我们还需要一个处理逻辑"或"的SearchCriterion对象。同我们实现逻辑"与"一样,我们可以使用类似的方法实现逻辑"或"(创建一个EitherOfTwoCriteria类)。但是,我们还可以使用另一种方法实现。

首先,我们在接口SearchCriterion上使用标注@FunctionalInterface。然后,在SearchCriterionFactory类中新增一个公有静态方法,命名为newEitherOfTwoCriteria()。类似的,该方法接收两个SearchCriterion对象,并返回一个新的SearchCriterion对象。

这里可以使用Lambda表达式,让Java编译器为我们创建一个实现了SearchCriterion接口的匿名类。示例代码如下所示。

public static SearchCriterion newEitherOfTwoCriteria(SearchCriterion a, SearchCriterion b) {
  return (Course course) -> a.isSatisfied(course) || b.isSatisfied(course);
}

步骤五

最后,我们再来整理一下StudentCenter类中提供的成员方法。我们在StudentCenter类中新增一个成员方法,其原型如下。

我们"借用"方法findCourse(CourseSearch search)来实现这个新方法,即在新方法中,实时的创建一个CourseSearch对象,将新方法的入参SearchCriterion"适配"到CourseSearch对象上。

public Iterator<Course> findCourse(SearchCriterion criterion){
  return findCourse(CourseSearch.builder().criterion(criterion::isSatisfied).build());
}

参考文档

  1. Java编程语言的基本概念
  2. 设计模式
  3. Maven工程管理工具
Copyright  2019 Little Waterdrop, LLC. All Rights Reserved.