Как перебрать список предикатов - PullRequest
4 голосов
/ 08 февраля 2020

У меня есть приложение весенней загрузки, и у нас есть application.yml с набором флагов функций

featureFlag:
    featureOne:true
    featureTwo:true
    featureThree:true
    featureFour:false

Затем этот файл читается этим классом

@Configuration
@ConfigurationProperties(prefix="featureFlag")
public class FeatureFlag{

private Boolean featureOne;
private Boolean featureTwo;
private Boolean featureThree;
private Boolean featureFour;
/*The predicates based on the feature flags*/

private Predicate<FeatureFlag> isFeatureFlagOneEnabled = featureFlag.isFeatureOne();
private Predicate<FeatureFlag> isFeatureFlagTwoEnabled = featureFlag.isFeatureTwo();
private Predicate<FeatureFlag> isFeatureFlagThreeEnabled = featureFlag.isFeatureThree();
private Predicate<FeatureFlag> isFeatureFlagFourEnabled = featureFlag.isFeatureFour();
}

Я хочу передать фактический предикат и повторить каждый из них, но я хочу знать, могу ли я сделать обобщенную c функцию, которую я передаю список Предикатов с его значением, которое будет проверено, и если все они истинны, функция возвращает мне true, иначе false

Затем в этот класс добавьте такой код, потому что я хочу сгенерировать этот список по требованию, например, у меня есть клиент x, который покупает featureOne и featureTwo, в этом примере я создаю список вроде этого

Set<Predicate<FeatureFlag>> rulesForClientX = new HashSet<>();
rulesForClientX.add(isFeatureFlagOneEnabled);
rulesForClientX.add(isFeatureFlagTwoEnabled);

Затем я хочу создать спецификацию c logi c для этого клиента и передать ему список ранее созданных предикатов, но я думаю, что мне нужно что-то вроде этого

Function<List<Predicate<FeatureFlag>>, Boolean> iteratePredicates = (predicates) -> { 
    //test each predicate and return true if all of them are true otherwise return false
}

Ответы [ 2 ]

4 голосов
/ 08 февраля 2020

Вы можете создать метод, который принимает Set<Predicate<FeatureFlag>> и значение, затем вы можете передавать поток предикатов и использовать allMatch

public boolean testPredicates(Set<Predicate<FeatureFlag>> predicates, Integer value) {
  return predicates.stream().allMatch(pre->pre.test(value));

 }
2 голосов
/ 08 февраля 2020

Цепочка Predicate s

То, на что вы должны рассчитывать, - это цепочка предикатов, которые у вас есть.

Я передаю список предикатов с его значением, которое нужно проверить, и если все они верны, функция возвращает мне true, иначе false

В зависимости от ваших требований это должно выглядеть так:

public Predicate<FeatureFlag> chainPredicates(Set<Predicate<FeatureFlag>> predicates) {
    return predicates.stream()
                     .reduce(Predicate::and) // all true
                     .orElse(p -> false); // or false
}

Потребление Predicate

Далее, вы можете легко использовать этот Predicate как

boolean testFeatureFlag(Set<Predicate<FeatureFlag>> predicates, FeatureFlag value) {
    return chainPredicates(predicates).test(value);
}

или в коллекции, например, List<FeatureFlag>, чтобы отфильтровать указанные c FeatureFlag s как:

List<FeatureFlag> selectiveFeatures(Set<Predicate<FeatureFlag>> predicates, List<FeatureFlag> featureFlags) {
    Predicate<FeatureFlag> flagPredicate  = chainPredicates(predicates);
    return featureFlags.stream()
            .filter(flagPredicate)
            .collect(Collectors.toList());
}
...