如何将策略模式与自定义排序策略一起使用?

时间:2018-09-24 17:58:53

标签: java design-patterns strategy-pattern

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

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

该端点应返回按年龄(年龄较小)排序的人,如果他们具有相同的年龄,则是头发的人,然后是纯素食的人。

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

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

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

name

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

所以我在这里有两个问题:

在这种情况下,策略模式是否是最佳设计模式?

如何使应用的策略数组更通用?

1 个答案:

答案 0 :(得分:0)

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

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;
  }
}

通过这种方式,您可以从外部配置获取比较器列表。 使用杰克逊的示例:

@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"
  }
]