用 Java 构建简单的规则引擎

在软件开发中,我们经常需要应用一组规则或条件来过滤或处理数据。使用传统的 if 和 else 语句管理这些规则可能会变得繁琐且难以维护。规则引擎提供了一种更灵活、更有条理的方法来定义和执行这些规则。在本文中,我们将探讨如何使用函数式编程原理在 Java 中构建一个简单的规则引擎。

先决条件
在我们深入构建规则引擎之前,让我们先定义必要的组件:

规则:
规则表示我们想要评估的条件或标准。它由一个谓词组成,该谓词确定给定对象是否满足规则的标准(使用 Enum 或 Map<key,value> )(在本部分中我使用 enum)。

规则引擎:
规则引擎负责管理一组规则,并将它们应用于一组对象,根据定义的规则对对象进行过滤,并返回过滤结果。

目标对象:
我们将使用一个简单的 Person 类作为示例对象,我们想使用规则对其进行过滤。它具有姓名和年龄等属性。

构建规则引擎
让我们开始一步一步构建我们的规则引擎:

定义规则:我们首先使用名为 Rule 的枚举来定义规则。枚举中的每个规则代表我们要评估的特定条件或标准。例如,在我们的代码中,我们定义了两个规则:AGE_GREATER_THAN_30 和 NAME_STARTS_WITH_B。每个规则都有一个相应的谓词,用于定义规则的条件。

import java.util.function.Predicate; 

//你可以有很多枚举来管理规则或条件
public  enum  Rule  implements  TestRule { 
    AGE_GREATER_THAN_30(person -> person.getAge() > 30 ), 
    NAME_STARTS_WITH_B(person -> person.getName().startsWith(
"B" )); 

    private  final Predicate<Person> predicate; 

    Rule(Predicate<Person> predicate) { 
        this .predicate = predicate; 
    } 

    public Predicate<Person> getPredicate () { 
        return predicate; 
    } 
}

创建规则引擎:
接下来,我们创建 RuleEngine 类。该类将负责规则的管理和执行。它维护一个规则列表,并提供添加新规则和根据这些规则过滤对象的方法。

实现过滤逻辑
在 RuleEngine 类的 filter 方法中,我们遍历对象列表并使用 Java 8 Stream API 中的 allMatch 方法应用每条规则。此方法检查给定对象的所有规则是否都通过。如果所有规则都通过,我们将该对象添加到过滤列表中。

public interface TestRule {
    <T> Predicate<T> getPredicate();
}
import java.util.ArrayList;
import java.util.List;

public class RuleEngine<T> {
    private List<TestRule> rules;

    public RuleEngine() {
        this.rules = new ArrayList<>();
    }

    public void addRule(TestRule rule) {
        rules.add(rule);
    }

    public List<T> filter(List<T> items) {
        List<T> filteredItems = new ArrayList<>();
        for (T item : items) {
            if (rules.stream().allMatch(rule -> rule.getPredicate().test(item))) {
                filteredItems.add(item);
            }
        }
        return filteredItems;
    }
}
public class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}


最后
在主类中,我们演示了规则引擎的用法。我们创建了一个 Person 对象列表,并用两条规则初始化了 RuleEngine:AGE_GREATER_THAN_30 和 NAME_STARTS_WITH_B。然后,我们调用规则引擎的过滤器方法,并将 Person 对象列表传入。规则引擎会对每个人应用规则,并返回过滤后的列表。

最后,我们遍历过滤后的列表,打印出符合指定规则的人名。

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Person> people = List.of(
                new Person("Alice", 25),
                new Person(
"Bob", 31),
                new Person(
"Charlie", 35)
        );

        RuleEngine<Person> ruleEngine = new RuleEngine<>();
        ruleEngine.addRule(Rule.AGE_GREATER_THAN_30);
        ruleEngine.addRule(Rule.NAME_STARTS_WITH_B);

        List<Person> filteredPeople = ruleEngine.filter(people);

//this part only print result 
        for (Person person : filteredPeople) {
            System.out.println(person.getName());
        }
    }
}

结论
在本文中,我们了解了如何用 Java 构建一个简单的规则引擎。规则引擎允许我们使用谓词定义规则,并将其应用于对象集合。利用函数式编程原则,我们可以创建一个灵活、可扩展的规则引擎,并将其用于各种场景。

通过理解这里介绍的概念和代码,您可以在此基础上扩展,创建更复杂的规则引擎,以满足您的特定需求。
https://github.com/KiaShamaei/ruleEngine