readme

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

需求分析

我们在上一个项目中创建了三个新类;它们实现了SearchCriterion接口。NameBasedSearchCriterion类可用于根据课程名称查询课程;CombineTwoSearchCriteria类使用逻辑"与"连接两个查询条件。我们还使用了一个匿名类,将两个查询条件通过逻辑"或"连接在一起。通过这三个类,我们可以创建任意复杂的、基于名称查询的查询请求CourseSearch对象。

步骤一

我们将在本项目中进一步增强课程查询的功能。我们首先在com.littlewaterdrop.search包中新增一个类KeywordBasedCriterion。它实现了SearchCriterion接口,用于检查课程名称是否包含一个关键字。该类包含了一个构造函数,用于传递待查找的关键字。成员方法isSatisfied()则判断传入的课程名称是否包含该关键字。在做关键字匹配时,大小写不敏感。例如,我们认为"Computer"和"computer"是相同的关键字。

我们还需要在com.littlewaterdrop.search包中的SearchCriterionFactory类中新增一个公有静态方法newKeywordBasedCriterion()方法,根据输入参数keyword,创建一个KeywordBasedCriterion类对象。这个静态方法的原型如下所示。

public class SearchCriterionFactory {
    public static KeywordBasedCriterion newKeywordBasedCriterion(String keyword);
}

步骤二

KeywordBasedCriterion实现了基于一个关键字的查询,我们现在来实现基于多个关键字的查询。类似的,这里同样有逻辑"与"和逻辑"或"两种场景。它们分别表示查询满足所有关键字的课程和查询满足其中一个关键字的课程。我们将使用适配模式实现这两个功能。

我们在com.littlewaterdrop.search包中创建一个新类MultiKeywordBasedCriterion。它包含一个构造函数,接收一个字符串数组,表示多个关键字。它的isSatisfied()检查课程的名称是否包含所有的关键字。这里,我们可以使用适配模式,使用我们已经实现的KeywordBasedCriterion和CombineTwoSearchCriteria类来实现MultiKeywordBasedCriterion。

public class MultiKeywordBasedCriterion {
    public boolean isSatisfied(Course course);
}

类似的,我们还需要在com.littlewaterdrop.search包中的SearchCriterionFactory类中新增一个公有静态方法newMultipleKeywordBasedCriterion()方法,根据输入参数keywords,创建一个MultiKeywordBasedCriterion类对象。这里我们可以使用可变长度的参数来接收多个关键字。这个静态方法的原型如下所示。

public class SearchCriterionFactory {
    public static MultiKeywordBasedCriterion newMultiKeywordBasedCriterion(String ...keywords);
}

步骤三

在实现逻辑"与"时,我们可以使用匿名类和Lambda表达式,让Java编译器帮助我们创建一个匿名类,实现了SearchCriterion接口。在com.littlewaterdrop.search包中的SearchCriterionFactory类中新增一个公有静态方法newMultipleEitherOfKeywordBasedCriterion()方法。该方法使用可变长度的参数来接收多个关键字。这个静态方法的原型如下所示。

public static SearchCriterion newMultipleEitherOfKeywordBasedCriterion(String ...keywords) {
    SearchCriterion alwaysNotSatisfiedCriterion = (x)->false;
    return Arrays.stream(keywords)  // stream of String
            .map(SearchCriterionFactory::newKeywordBasedCriterion) // stream of KeywordBasedCriterion
            .map(x->(SearchCriterion)x) // stream of SearchCriterion
            .reduce(alwaysNotSatisfiedCriterion, SearchCriterionFactory::newEitherOfTwoCriteria) // combine all of them
            ;
}

参考文档

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