java - 如何将策略模式与自定义排序策略结合使用?

标签 java design-patterns strategy-pattern

我想知道我使用的方法是否最适合这种情况。

我正在开发一个 REST API,并且有一个端点必须返回人员对象列表。例如,假设 person 类有年龄(int)、头发和素食主义者(都是 boolean 值)。

该端点应返回按年龄排序的人员(首先是年轻的人员),如果年龄相同,则返回有头发的人员,最后是素食主义者。

排序策略可以更改,因为它们是从配置文件中读取的。因此,端点可以首先返回纯素食者,然后返回有头发的人,最后按年龄返回。

正如我所看到的,有不同的策略可以应用,我认为最好的方法是使用策略模式(我也考虑过装饰器,但由于策略可以改变,我不知道如何应用它)。我创建了一个返回比较器的接口(interface),然后我有可以应用的策略实现(头发、年龄和素食主义者),它返回一个比较器。我从配置文件中读取策略并将它们保存到字符串数组中。

到目前为止,我只使用三种策略

array.stream.sorted(strategy[0].compare().thenComparing(strategy[1].compare()).thencomparing...)

但我看到一个明显的问题,即这是不可扩展的,因为如果我再添加一个策略,它将不会被处理。

所以我有两个问题:

策略模式是适合这种排序情况的最佳设计模式吗?

我怎样才能使应用的策略数组更加通用?

最佳答案

我会添加一个新的比较器类:

public abstract class PersonComparator implements Comparator<Person> {
}

添加每种类型的可能比较器:

public class AgeComparator extends PersonComparator {
// implement comparing logic
}
public class VeganComparator extends PersonComparator {
// implement comparing logic
}

添加一个新服务来获取比较器进行封装​​:

public class PersonService {

  public Comparator<Person> getComparator() {
    // obtain from configuration the list of comparators
    List<PersonComparator> comparators = //..
    Comparator<Person> comparator = comparators.get(0);
    for (int i = 1; i < comparators.size(); i++) {
        comparator = comparator.thenComparing(comparators.get(i));
    }
    return comparator;
  }
}

这样,您就可以从外部配置中获取比较器列表。 使用 jackson 的示例:

@JsonTypeInfo(
            use = JsonTypeInfo.Id.NAME,
            include = JsonTypeInfo.As.PROPERTY,
            property = "type")
    @JsonSubTypes({
            @JsonSubTypes.Type(value = AgeComparator.class, name = "age"),
            @JsonSubTypes.Type(value = VeganComparator.class, name = "vegan")
    })
    public abstract class PersonComparator implements Comparator<Person> {

        private String type;

        //getters and setters
    }

配置为:

[
  {
    "type": "age"
  },
  {
    "type": "vegan"
  }
]

关于java - 如何将策略模式与自定义排序策略结合使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52484910/

相关文章:

java - 是否可以在 Stash 预接收 Hook 中使用 pep8 和 yapf?

java - 有趣的 API 模式

java - 通用 Java 模式识别库——如 List<Object> 的正则表达式

java - 策略模式,将函数传递给父方法

dependency-injection - 在 nest.js 中实现策略

java - 如何使用所有参数都为强制性的构建器模式?

java - 二分查找CompareTo Java

java - Spring data mongo GridFsOperation.findOne 找不到第一个

java - 如果我可以在创建者类中拥有多个工厂方法,为什么我需要抽象工厂模式?

javascript - 有哪些使用 JavaScript 实现设计模式的示例?