【问题标题】:How to use strategy pattern with custom sorting strategies?如何将策略模式与自定义排序策略一起使用?
【发布时间】:2018-09-24 17:58:53
【问题描述】:

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

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

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

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

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

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

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

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

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

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

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

【问题讨论】:

    标签: java design-patterns strategy-pattern


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-29
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 2019-12-21
      • 2011-06-30
      相关资源
      最近更新 更多