是否有用于在Java中实现基本"规则链"的标准库/ API /工具?

iX3*_*iX3 5 java

我正在编写一个servlet,它将根据一些用户可定义的规则有条件地修改HTTP头.(编辑:这些规则在启动时读取的XML文件中定义.)例如,如果响应标头尚不存在,则将"X-UA-Compatible:IE = edge,chrome = 1"添加到响应标头中如果请求指定了与已知模式匹配的"User-Agent"标头.没有任何更好的想法,我试图让我自己的POJO代表这些规则.它"有效"但我觉得必须有更标准或更灵活的方法来做到这一点.

是否有可以解决此问题的通用库或工具(无论是内置程序还是第三方)?我已经听过并读过一些关于"规则引擎"的内容,但它们似乎是更复杂/更重的工具,并不像我的那样简单.

为了说明我正在尝试做什么,我创建了一个简化程序,根据"条件"(例如"是偶数")将"规则"应用于数字.在这里,对不起它有点冗长.

Main.java

package my.example;

import java.util.*;

import my.example.conditions.*;
import my.example.rules.*;

public class Main {

    public static void main(String args[]) {
        // Some sample objects to evaluate
        Collection<Integer> numbers = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8);
        print(numbers);

        // Define rules
        Collection<Rule<Integer>> rules = new ArrayList<Rule<Integer>>();
        rules.add(createRuleToMultiplyEvenNumbersBy4());
        rules.add(createRuleToAdd1ToEveryNumber());

        // Process the rules for each sample object
        Collection<Integer> newNumbers = new ArrayList<Integer>();
        for (Integer number : numbers) {
            Integer newNumber = number;
            for (Rule<Integer> rule : rules)
                newNumber = rule.apply(newNumber);
            newNumbers.add(newNumber);
        }

        print(newNumbers);
    }

    private static Rule<Integer> createRuleToMultiplyEvenNumbersBy4() {
        MultiplyNumberRule rule = new MultiplyNumberRule(true, 4);
        rule.addCondition(new NumberIsEvenCondition());
        return rule;
    }

    private static Rule<Integer> createRuleToAdd1ToEveryNumber() {
        AddNumberRule rule = new AddNumberRule(true, 1);
        rule.addCondition(new ConstantCondition<Integer>(true));
        return rule;
    }

    private static void print(Collection<Integer> numbers) {
        System.out.print("Numbers: ");
        for (Integer number : numbers) {
            System.out.print(number);
            System.out.print(" ");
        }
        System.out.print("\r\n");
    }   


}
Run Code Online (Sandbox Code Playgroud)

Condition.java

package my.example.conditions;

public interface Condition<T> {
    boolean appliesTo(T obj);
}
Run Code Online (Sandbox Code Playgroud)

ConstantCondition.java

package my.example.conditions;

public class ConstantCondition<T> implements Condition<T> {
    private boolean constant;

    public ConstantCondition(boolean alwaysReturnThisValue) {
        constant = alwaysReturnThisValue;
    }

    @Override
    public boolean appliesTo(T target) {
        return constant;
    }
}
Run Code Online (Sandbox Code Playgroud)

NumberIsEvenCondition.java

package my.example.conditions;

public class NumberIsEvenCondition implements Condition<Integer> {
    @Override
    public boolean appliesTo(Integer i) {
        return (i % 2 == 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

Rule.java

package my.example.rules;

public interface Rule<T> {
    T apply(T target);
}
Run Code Online (Sandbox Code Playgroud)

AbstractRule.java

package my.example.rules;

import java.util.*;

import my.example.conditions.Condition;
public abstract class AbstractRule<T> implements Rule<T> {
    private Collection<Condition<T>> conditions;
    private boolean requireAllConditions;

    public AbstractRule(boolean requireAllConditions) {
        conditions = new ArrayList<Condition<T>>();
        this.requireAllConditions = requireAllConditions;
    }

    public void addCondition(Condition<T> condition) {
        conditions.add(condition);
    }

    @Override
    public T apply(T target) {
        boolean isApplicable;
        if (requireAllConditions)
            isApplicable = allConditionsSatisfied(target);
        else
            isApplicable = atLeastOneConditionSatisfied(target);

        if (isApplicable)
            target = process(target);

        return target;
    }

    // Check if all conditions are met
    protected boolean allConditionsSatisfied(T target) {
        for (Condition<T> condition : conditions) {
            if (!condition.appliesTo(target))
                return false;
        }       
        return true;
    }

    // Check if any conditions are met
    protected boolean atLeastOneConditionSatisfied(T target) {
        for (Condition<T> condition : conditions) {
            if (condition.appliesTo(target))
                return true;
        }       
        return false;
    }

    abstract T process(T target);

}
Run Code Online (Sandbox Code Playgroud)

AddNumberRule.java

package my.example.rules;

public class AddNumberRule extends AbstractRule<Integer> {
    private Integer addend;

    public AddNumberRule(boolean requireAllConditions) {
        this(requireAllConditions, 0);
    }

    public AddNumberRule(boolean requireAllConditions, Integer addend) {
        super(requireAllConditions);
        this.addend = addend;
    }

    @Override
    public Integer process(Integer i) {
        return i + addend;
    }
}
Run Code Online (Sandbox Code Playgroud)

MultiplyNumberRule.java

package my.example.rules;

public class MultiplyNumberRule extends AbstractRule<Integer> {
    private Integer factor;

    public MultiplyNumberRule(boolean requireAllConditions) {
        this(requireAllConditions, 1);
    }

    public MultiplyNumberRule(boolean requireAllConditions, Integer factor) {
        super(requireAllConditions);
        this.factor = factor;
    }

    @Override
    public Integer process(Integer i) {
        return i * factor;
    }
}
Run Code Online (Sandbox Code Playgroud)

Lui*_* E. 1

好吧,我会使用Commons Chain

用于组织复杂处理流程的执行的一种流行技术是“责任链”模式,如经典的“四人帮”设计模式书中所描述的(以及许多其他地方)。尽管实现此设计模式所需的基本 API 合约非常简单,但拥有一个有助于使用该模式的基本 API 非常有用,并且(更重要的是)鼓励来自多个不同来源的命令实现的组合。

这是一种常见的设计模式,猜测适合您的问题