EasyRule源码:工厂方法模式之规则创建源码分析

这篇具有很好参考价值的文章主要介绍了EasyRule源码:工厂方法模式之规则创建源码分析。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.规则创建方式

1.1.@Rule注解

1.2.链式编程

1.3.表达式方式

1.4.文件脚本DSL方式

2.创建的规则类(产品类)

3.规则工厂类

3.1 RuleDefinition类

3.2 组合规则创建

3.3 单一规则创建


EasyRule框架的源码解析见上篇文章:EasyRule源码:EasyRule框架源码分析

本文主要对EasyRule框架中应用的工厂方法模式---规则创建进行源码解析;

1.规则创建方式

EasyRule框架支持的创建规则的方法有很多种,如下是几种规则创建的方式:

1.1.@Rule注解

利用注解方式完成规则的创建:

@Rule(name = "weather rule", description = "if it rains then take an umbrella")
public class WeatherRule {

    @Condition
    public boolean itRains(@Fact("rain") boolean rain) {
        return rain;
    }
    
    @Action
    public void takeAnUmbrella() {
        System.out.println("It rains, take an umbrella!");
    }
}

1.2.链式编程

Rule weatherRule = new RuleBuilder()
        .name("weather rule")
        .description("if it rains then take an umbrella")
        .when(facts -> facts.get("rain").equals(true))
        .then(facts -> System.out.println("It rains, take an umbrella!"))
        .build();

1.3.表达式方式

Rule weatherRule = new MVELRule()
        .name("weather rule")
        .description("if it rains then take an umbrella")
        .when("rain == true")
        .then("System.out.println(\"It rains, take an umbrella!\");");

1.4.文件脚本DSL方式

weather-rule.yml文件定义:

name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:
  - "System.out.println(\"It rains, take an umbrella!\");"

或者weather-rule.json文件定义:

[
  {
    "name": "weather rule",
    "description": "if it rains then take an umbrella",
    "priority": 1,
    "condition": "rain == true",
    "actions": [
      "System.out.println(\"It rains, take an umbrella!\");"
    ]
  }
]

其中,前3种方式都是通过Java编码的方式实现规则创建,第4种文件脚本DSL方式通过指定json或yml文件的方式完成规则创建,该种方式的好处包括:

  • 规则创建更加简单易懂
  • 可以支持规则热发布

在EasyRule框架源码中,对文件脚本DSL方式的解析是通过巧妙利用工厂方法模式来完成规则创建的,这里的抽象工厂类就是AbstractRuleFactory,创建的产品类是Rule具体实现类,下面重点从产品类和工厂类角度对该部分进行源码解析;

2.创建的规则类(产品类)

具体的规则类整体类图如下:

EasyRule源码:工厂方法模式之规则创建源码分析,规则引擎,框架,工厂方法模式,java,后端

规则类包括单一规则(SpELRule&MVELRule&JexlRule)和组合规则(CompositeRule),说明如下:

BasicRule:Rule接口的基础实现类,管理规则名称、描述和优先级

DefaultRule:默认规则实现类,包含Condition和多个Action

SpELRule&MVELRule&JexlRule:支持SpEL、MVEL、Jexl表达式定义的Condition和Action

CompositeRule:组合规则,对多个规则组合管理

ActivationRuleGroup&ConditionalRuleGroup&UnitRuleGroup:封装不同的组合规则管理策略

 以SpELRule为例说明,SpELRule源码如下:

/**
 * A {@link Rule} implementation that uses 
 * <a href="https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#expressions">SpEL</a>
 * to evaluate and execute the rule.
 *
 * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
 */
public class SpELRule extends BasicRule {

    private Condition condition = Condition.FALSE;
    private final List<Action> actions = new ArrayList<>();
    private final ParserContext parserContext;
    private BeanResolver beanResolver;

    /**
     * Create a new SpEL rule.
     */
    public SpELRule() {
        this(ParserContext.TEMPLATE_EXPRESSION);
    }

    /**
     * Create a new SpEL rule.
     * 
     * @param parserContext used when parsing expressions
     */
    public SpELRule(ParserContext parserContext) {
        super(Rule.DEFAULT_NAME, Rule.DEFAULT_DESCRIPTION, Rule.DEFAULT_PRIORITY);
        this.parserContext = parserContext;
    }

    /**
     * Create a new SpEL rule.
     *
     * @param beanResolver used to resolve bean references in expressions
     */
    public SpELRule(BeanResolver beanResolver) {
        super(Rule.DEFAULT_NAME, Rule.DEFAULT_DESCRIPTION, Rule.DEFAULT_PRIORITY);
        this.parserContext = ParserContext.TEMPLATE_EXPRESSION;
        this.beanResolver = beanResolver;
    }

    /**
     * Create a new SpEL rule.
     *
     * @param parserContext used when parsing expressions
     * @param beanResolver used to resolve bean references in expressions
     */
    public SpELRule(ParserContext parserContext, BeanResolver beanResolver) {
        super(Rule.DEFAULT_NAME, Rule.DEFAULT_DESCRIPTION, Rule.DEFAULT_PRIORITY);
        this.parserContext = parserContext;
        this.beanResolver = beanResolver;
    }

    /**
     * Set rule name.
     *
     * @param name of the rule
     * @return this rule
     */
    public SpELRule name(String name) {
        this.name = name;
        return this;
    }

    /**
     * Set rule description.
     *
     * @param description of the rule
     * @return this rule
     */
    public SpELRule description(String description) {
        this.description = description;
        return this;
    }

    /**
     * Set rule priority.
     *
     * @param priority of the rule
     * @return this rule
     */
    public SpELRule priority(int priority) {
        this.priority = priority;
        return this;
    }

    /**
     * Specify the rule's condition as SpEL expression.
     * @param condition of the rule
     * @return this rule
     */
    public SpELRule when(String condition) {
        this.condition = new SpELCondition(condition, parserContext, beanResolver);
        return this;
    }

    /**
     * Add an action specified as an SpEL expression to the rule.
     * @param action to add to the rule
     * @return this rule
     */
    public SpELRule then(String action) {
        this.actions.add(new SpELAction(action, parserContext, beanResolver));
        return this;
    }

    @Override
    public boolean evaluate(Facts facts) {
        return condition.evaluate(facts);
    }

    @Override
    public void execute(Facts facts) throws Exception {
        for (Action action : actions) {
            action.execute(facts);
        }
    }
}

如上,在SpELRule表达式实现中,支持SpEL表达式定义的Condition和Action,并分别实现了规则条件的解析和规则动作的执行;

3.规则工厂类

上述对json、yml 文件脚本进行解析并完成具体规则的创建都是通过规则工厂类来完成的;

规则工厂类图如下:

EasyRule源码:工厂方法模式之规则创建源码分析,规则引擎,框架,工厂方法模式,java,后端

首先看一下AbstractRuleFactory源码:

/**
 * Base class for rule factories.
 *
 * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
 */
public abstract class AbstractRuleFactory {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractRuleFactory.class);

    private static final List<String> ALLOWED_COMPOSITE_RULE_TYPES = Arrays.asList(
            UnitRuleGroup.class.getSimpleName(),
            ConditionalRuleGroup.class.getSimpleName(),
            ActivationRuleGroup.class.getSimpleName()
    );

    protected Rule createRule(RuleDefinition ruleDefinition) {
        if (ruleDefinition.isCompositeRule()) {
            return createCompositeRule(ruleDefinition);
        } else {
            return createSimpleRule(ruleDefinition);
        }
    }

    protected abstract Rule createSimpleRule(RuleDefinition ruleDefinition);

    protected Rule createCompositeRule(RuleDefinition ruleDefinition) {
        if (ruleDefinition.getCondition() != null) {
            LOGGER.warn(
                    "Condition '{}' in composite rule '{}' of type {} will be ignored.",
                    ruleDefinition.getCondition(),
                    ruleDefinition.getName(),
                    ruleDefinition.getCompositeRuleType());
        }
        if (ruleDefinition.getActions() != null && !ruleDefinition.getActions().isEmpty()) {
            LOGGER.warn(
                    "Actions '{}' in composite rule '{}' of type {} will be ignored.",
                    ruleDefinition.getActions(),
                    ruleDefinition.getName(),
                    ruleDefinition.getCompositeRuleType());
        }
        CompositeRule compositeRule;
        String name = ruleDefinition.getName();
        switch (ruleDefinition.getCompositeRuleType()) {
            case "UnitRuleGroup":
                compositeRule = new UnitRuleGroup(name);
                break;
            case "ActivationRuleGroup":
                compositeRule = new ActivationRuleGroup(name);
                break;
            case "ConditionalRuleGroup":
                compositeRule = new ConditionalRuleGroup(name);
                break;
            default:
                throw new IllegalArgumentException("Invalid composite rule type, must be one of " + ALLOWED_COMPOSITE_RULE_TYPES);
        }
        compositeRule.setDescription(ruleDefinition.getDescription());
        compositeRule.setPriority(ruleDefinition.getPriority());

        for (RuleDefinition composingRuleDefinition : ruleDefinition.getComposingRules()) {
            compositeRule.addRule(createRule(composingRuleDefinition));
        }

        return compositeRule;
    }

}

在上述源码中,分别通过方法createSimpleRule和方法createCompositeRule完成单一规则和组合规则的创建;

下面分别从单一规则创建和组合规则创建的角度分析工厂类具体的创建过程;

在分析工厂类创建逻辑之前,我们注意到工厂类的创建方法参数是RuleDefinition,首先看一下RuleDefinition的构造;

3.1 RuleDefinition类

RuleDefinition表示规则描述类,封装了规则的名称、描述、优先级以及包含的条件和执行的动作等;

RuleDefinition的定义如下:

/**
 * Rule definition as defined in a rule descriptor.
 * This class encapsulates the static definition of a {@link Rule}.
 *
 * Rule definitions are produced by a {@code RuleDefinitionReader}s
 * and consumed by rule factories to create rules.
 *
 * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
 */
public class RuleDefinition {

    private String name = Rule.DEFAULT_NAME;
    private String description = Rule.DEFAULT_DESCRIPTION;
    private int priority = Rule.DEFAULT_PRIORITY;
    private String condition;
    private List<String> actions = new ArrayList<>();
    private List<RuleDefinition> composingRules = new ArrayList<>();
    private String compositeRuleType;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getCondition() {
        return condition;
    }

    public void setCondition(String condition) {
        this.condition = condition;
    }

    public int getPriority() {
        return priority;
    }

    public void setPriority(int priority) {
        this.priority = priority;
    }

    public List<String> getActions() {
        return actions;
    }

    public void setActions(List<String> actions) {
        this.actions = actions;
    }

    public void setComposingRules(List<RuleDefinition> composingRuleDefinitions) {
        this.composingRules = composingRuleDefinitions;
    }

    public void setCompositeRuleType(String compositeRuleType) {
        this.compositeRuleType = compositeRuleType;
    }

    public String getCompositeRuleType() {
        return compositeRuleType;
    }

    public List<RuleDefinition> getComposingRules() {
        return composingRules;
    }

    public boolean isCompositeRule() {
        return !composingRules.isEmpty();
    }
}

RuleDefinition的构造是通过RuleDefinitionReader完成的,RuleDefinitionReader的定义如下:

/**
 * Strategy interface for {@link RuleDefinition} readers.
 *
 * @see JsonRuleDefinitionReader
 * @see YamlRuleDefinitionReader
 *
 * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
 */
@FunctionalInterface
public interface RuleDefinitionReader {

    /**
     * Read a list of rule definitions from a rule descriptor.
     *
     * <strong> The descriptor is expected to contain a collection of rule definitions
     * even for a single rule.</strong>
     *
     * @param reader of the rules descriptor
     * @return a list of rule definitions
     * @throws Exception if a problem occurs during rule definition reading
     */
    List<RuleDefinition> read(Reader reader) throws Exception;

}

read方法接受Reader输入,并返回解析结果RuleDefinition列表;

EasyRule框架源码中,提供了分别针对.json文件和.yml文件的Reader实现类: 

JsonRuleDefinitionReader:完成.json文件的解析,并构造RuleDefinition

YamlRuleDefinitionReader:完成.yml文件的解析,并构造RuleDefinition

RuleDefinitionReader的整体类图如下: 

EasyRule源码:工厂方法模式之规则创建源码分析,规则引擎,框架,工厂方法模式,java,后端

具体的解析逻辑封装到了抽象类接口中:

/**
 * Base class for {@link RuleDefinitionReader}s.
 *
 * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
 */
public abstract class AbstractRuleDefinitionReader implements RuleDefinitionReader {

    public List<RuleDefinition> read(Reader reader) throws Exception {
        List<RuleDefinition> ruleDefinitions = new ArrayList<>();
        Iterable<Map<String, Object>> rules = loadRules(reader);
        for (Map<String, Object> rule : rules) {
            ruleDefinitions.add(createRuleDefinition(rule));
        }
        return ruleDefinitions;
    }

    /**
     * Load rules from the given reader as an iterable of Maps.
     *
     * @param reader to read rules from
     * @return an iterable of rule Maps
     * @throws Exception if unable to load rules
     */
    protected abstract Iterable<Map<String, Object>> loadRules(Reader reader) throws Exception;

    /**
     * Create a rule definition.
     *
     * @param map of rule properties
     * @return a rule definition
     */
    protected RuleDefinition createRuleDefinition(Map<String, Object> map) {
        RuleDefinition ruleDefinition = new RuleDefinition();

        String name = (String) map.get("name");
        ruleDefinition.setName(name != null ? name : Rule.DEFAULT_NAME);

        String description = (String) map.get("description");
        ruleDefinition.setDescription(description != null ? description : Rule.DEFAULT_DESCRIPTION);

        Integer priority = (Integer) map.get("priority");
        ruleDefinition.setPriority(priority != null ? priority : Rule.DEFAULT_PRIORITY);

        String compositeRuleType = (String) map.get("compositeRuleType");

        String condition = (String) map.get("condition");
        if (condition == null && compositeRuleType == null) {
            throw new IllegalArgumentException("The rule condition must be specified");
        }
        ruleDefinition.setCondition(condition);

        List<String> actions = (List<String>) map.get("actions");
        if ((actions == null || actions.isEmpty()) && compositeRuleType == null) {
            throw new IllegalArgumentException("The rule action(s) must be specified");
        }
        ruleDefinition.setActions(actions);

        List<Object> composingRules = (List<Object>) map.get("composingRules");
        if ((composingRules != null && !composingRules.isEmpty()) && compositeRuleType == null) {
            throw new IllegalArgumentException("Non-composite rules cannot have composing rules");
        } else if ((composingRules == null || composingRules.isEmpty()) && compositeRuleType != null) {
            throw new IllegalArgumentException("Composite rules must have composing rules specified");
        } else if (composingRules != null) {
            List<RuleDefinition> composingRuleDefinitions = new ArrayList<>();
            for (Object rule : composingRules) {
                Map<String, Object> composingRuleMap = (Map<String, Object>) rule;
                composingRuleDefinitions.add(createRuleDefinition(composingRuleMap));
            }
            ruleDefinition.setComposingRules(composingRuleDefinitions);
            ruleDefinition.setCompositeRuleType(compositeRuleType);
        }

        return ruleDefinition;
    }
}

抽象方法loadRules交由子类具体实现,JsonRuleDefinitionReader和YamlRuleDefinitionReader的具体实现分别如下:

/**
 * Rule definition reader based on <a href="https://github.com/FasterXML/jackson">Jackson</a>.
 *
 * This reader expects an array of rule definitions as input even for a single rule. For example:
 *
 * <pre>
 *     [{rule1}, {rule2}]
 * </pre>
 *
 * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
 */
@SuppressWarnings("unchecked")
public class JsonRuleDefinitionReader extends AbstractRuleDefinitionReader {

    private final ObjectMapper objectMapper;

    /**
     * Create a new {@link JsonRuleDefinitionReader}.
     */
    public JsonRuleDefinitionReader() {
        this(new ObjectMapper());
    }

    /**
     * Create a new {@link JsonRuleDefinitionReader}.
     *
     * @param objectMapper to use to read rule definitions
     */
    public JsonRuleDefinitionReader(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    protected Iterable<Map<String, Object>> loadRules(Reader reader) throws Exception {
        List<Map<String, Object>> rulesList = new ArrayList<>();
        Object[] rules = objectMapper.readValue(reader, Object[].class);
        for (Object rule : rules) {
            rulesList.add((Map<String, Object>) rule);
        }
        return rulesList;
    }

}
/**
 * Rule definition reader based on <a href="https://github.com/FasterXML/jackson-dataformats-text/tree/master/yaml">Jackson Yaml</a>.
 *
 * This reader expects a collection of rule definitions as input even for a single rule. For example:
 *
 * <pre>
 *     rule1
 *     ---
 *     rule2
 * </pre>
 *
 * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
 */
@SuppressWarnings("unchecked")
public class YamlRuleDefinitionReader extends AbstractRuleDefinitionReader {

    private final Yaml yaml;

    /**
     * Create a new {@link YamlRuleDefinitionReader}.
     */
    public YamlRuleDefinitionReader() {
        this(new Yaml());
    }

    /**
     * Create a new {@link YamlRuleDefinitionReader}.
     *
     * @param yaml to use to read rule definitions
     */
    public YamlRuleDefinitionReader(Yaml yaml) {
        this.yaml = yaml;
    }

    @Override
    protected Iterable<Map<String, Object>> loadRules(Reader reader) {
        List<Map<String, Object>> rulesList = new ArrayList<>();
        Iterable<Object> rules = yaml.loadAll(reader);
        for (Object rule : rules) {
            rulesList.add((Map<String, Object>) rule);
        }
        return rulesList;
    }
}

至此,借助RuleDefinitionReader完成了RuleDefinition的解析;

3.2 组合规则创建

在方法createRule实现中,根据解析结果中是否包含组合规则会路由到不同的创建逻辑;

包含组合规则的情况下,会构造具体的组合规则,如下:

    protected Rule createCompositeRule(RuleDefinition ruleDefinition) {
        if (ruleDefinition.getCondition() != null) {
            LOGGER.warn(
                    "Condition '{}' in composite rule '{}' of type {} will be ignored.",
                    ruleDefinition.getCondition(),
                    ruleDefinition.getName(),
                    ruleDefinition.getCompositeRuleType());
        }
        if (ruleDefinition.getActions() != null && !ruleDefinition.getActions().isEmpty()) {
            LOGGER.warn(
                    "Actions '{}' in composite rule '{}' of type {} will be ignored.",
                    ruleDefinition.getActions(),
                    ruleDefinition.getName(),
                    ruleDefinition.getCompositeRuleType());
        }
        CompositeRule compositeRule;
        String name = ruleDefinition.getName();
        switch (ruleDefinition.getCompositeRuleType()) {
            case "UnitRuleGroup":
                compositeRule = new UnitRuleGroup(name);
                break;
            case "ActivationRuleGroup":
                compositeRule = new ActivationRuleGroup(name);
                break;
            case "ConditionalRuleGroup":
                compositeRule = new ConditionalRuleGroup(name);
                break;
            default:
                throw new IllegalArgumentException("Invalid composite rule type, must be one of " + ALLOWED_COMPOSITE_RULE_TYPES);
        }
        compositeRule.setDescription(ruleDefinition.getDescription());
        compositeRule.setPriority(ruleDefinition.getPriority());

        for (RuleDefinition composingRuleDefinition : ruleDefinition.getComposingRules()) {
            compositeRule.addRule(createRule(composingRuleDefinition));
        }

        return compositeRule;
    }

这里实际上通过简单工厂模式完成了3种不同组合规则的创建,同时递归调用方法createRule完成了规则的递归构造,嵌套逻辑;

3.3 单一规则创建

不包含组合规则的条件下,调用createSimpleRule方法完成单一规则的创建,这里的具体实现包括:

SpELRuleFactory:创建SpEL表达式定义规则的工厂类

MVELRuleFactory:创建MVEL表达式定义规则的工厂类

JexlRuleFactory:创建Jexl表达式定义规则的工厂类

这里以SpELRuleFactory说明(其它类似),SpELRuleFactory源码如下:

/**
 * Factory to create {@link SpELRule} instances.
 *
 * @author Mahmoud Ben Hassine (mahmoud.benhassine@icloud.com)
 */
public class SpELRuleFactory extends AbstractRuleFactory {

    private final RuleDefinitionReader reader;
    private BeanResolver beanResolver;
    private ParserContext parserContext;

    /**
     * Create a new {@link SpELRuleFactory} with a given reader.
     *
     * @param reader used to read rule definitions
     * @see YamlRuleDefinitionReader
     * @see JsonRuleDefinitionReader
     */
    public SpELRuleFactory(RuleDefinitionReader reader) {
        this(reader, ParserContext.TEMPLATE_EXPRESSION);
    }

    /**
     * Create a new {@link SpELRuleFactory} with a given reader.
     *
     * @param reader used to read rule definitions
     * @param parserContext used to parse SpEL expressions
     * @see YamlRuleDefinitionReader
     * @see JsonRuleDefinitionReader
     */
    public SpELRuleFactory(RuleDefinitionReader reader, ParserContext parserContext) {
        this.reader = reader;
        this.parserContext = parserContext;
    }

    /**
     * Create a new {@link SpELRuleFactory} with a given reader.
     *
     * @param reader used to read rule definitions
     * @param beanResolver used to resolve bean references in SpEL expressions
     * @see YamlRuleDefinitionReader
     * @see JsonRuleDefinitionReader
     */
    public SpELRuleFactory(RuleDefinitionReader reader, BeanResolver beanResolver) {
        this.reader = reader;
        this.beanResolver = beanResolver;
    }

    /**
     * Create a new {@link SpELRuleFactory} with a given reader.
     *
     * @param reader used to read rule definitions
     * @param parserContext used to parse SpEL expressions
     * @param beanResolver used to resolve bean references in SpEL expressions
     * @see YamlRuleDefinitionReader
     * @see JsonRuleDefinitionReader
     */
    public SpELRuleFactory(RuleDefinitionReader reader, ParserContext parserContext, BeanResolver beanResolver) {
        this.reader = reader;
        this.parserContext = parserContext;
        this.beanResolver = beanResolver;
    }

    /**
     * Create a new {@link SpELRule} from a Reader.
     * 
     * The rule descriptor should contain a single rule definition.
     * If no rule definitions are found, a {@link IllegalArgumentException} will be thrown.
     * If more than a rule is defined in the descriptor, the first rule will be returned.
     *
     * @param ruleDescriptor descriptor of rule definition
     * @return a new rule
     * @throws Exception if unable to create the rule from the descriptor
     */
    public Rule createRule(Reader ruleDescriptor) throws Exception {
        List<RuleDefinition> ruleDefinitions = reader.read(ruleDescriptor);
        if (ruleDefinitions.isEmpty()) {
            throw new IllegalArgumentException("rule descriptor is empty");
        }
        return createRule(ruleDefinitions.get(0));
    }

    /**
     * Create a set of {@link SpELRule} from a Reader.
     *
     * @param rulesDescriptor descriptor of rule definitions
     * @return a set of rules
     * @throws Exception if unable to create rules from the descriptor
     */
    public Rules createRules(Reader rulesDescriptor) throws Exception {
        Rules rules = new Rules();
        List<RuleDefinition> ruleDefinitions = reader.read(rulesDescriptor);
        for (RuleDefinition ruleDefinition : ruleDefinitions) {
            rules.register(createRule(ruleDefinition));
        }
        return rules;
    }

    protected Rule createSimpleRule(RuleDefinition ruleDefinition) {
        SpELRule spELRule = new SpELRule(parserContext, beanResolver)
                .name(ruleDefinition.getName())
                .description(ruleDefinition.getDescription())
                .priority(ruleDefinition.getPriority())
                .when(ruleDefinition.getCondition());
        for (String action : ruleDefinition.getActions()) {
            spELRule.then(action);
        }
        return spELRule;
    }

}

上述createSimpleRule方法的实现中,构造了SpELRule的具体实例,完成了单一规则的创建;

至此,EasyRule框架通过工厂方法模式,完成了文件脚本规则(.json、.yml)的创建。

附工厂方法模式UML类图:

EasyRule源码:工厂方法模式之规则创建源码分析,规则引擎,框架,工厂方法模式,java,后端文章来源地址https://www.toymoban.com/news/detail-721747.html

到了这里,关于EasyRule源码:工厂方法模式之规则创建源码分析的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [设计模式Java实现附plantuml源码~创建型] 产品族的创建——抽象工厂模式

    前言: 为什么之前写过Golang 版的设计模式,还在重新写 Java 版? 答:因为对于我而言,当然也希望对正在学习的大伙有帮助。Java作为一门纯面向对象的语言,更适合用于学习设计模式。 为什么类图要附上uml 因为很多人学习有做笔记的习惯,如果单纯的只是放一张图片,那

    2024年01月22日
    浏览(62)
  • 篇二:工厂方法模式:灵活创建对象

    篇二: “工厂方法模式:灵活创建对象” 开始本篇文章之前先推荐一个好用的学习工具,AIRIght,借助于AI助手工具,学习事半功倍。欢迎访问:http://airight.fun/。 另外有2本不错的关于设计模式的资料,分享出来与大家学习参考。 链接:https://pan.baidu.com/s/1RmhQF_o1CdK8U7s5KeILog?

    2024年02月14日
    浏览(40)
  • 工厂方法模式:创建对象的灵活与扩展

    欢迎来到设计模式系列的第三篇文章!在前两篇文章中,我们已经学习了设计模式的基本概念以及单例模式的应用。 今天,我们将深入探讨第二个模式——工厂方法模式。 工厂方法模式简介 工厂方法模式是一种创建型设计模式,它提供了一种方法来创建对象,但是由子类决

    2024年02月10日
    浏览(45)
  • 【Java 设计模式】创建型之工厂方法模式

    在软件开发中,工厂方法模式是一种常见的创建型设计模式, 它提供了一种将对象的实例化延迟到子类的方法 。工厂方法模式通过定义一个创建对象的接口,但是让子类决定实例化哪个类。在本文中,我们将介绍 Java 设计模式中的工厂方法模式,了解其定义、使用场景以及

    2024年01月17日
    浏览(62)
  • Factory Method Pattern 工厂方法模式简介与 C# 示例【创建型】【设计模式来了】

    一句话解释:   实体类和工厂类均为单独实现,不影响已实现的类,方便扩展。 工厂方法模式(Factory Method Pattern)是一种创建型模式,它允许客户端通过工厂方法来创建对象,而不是直接使用构造函数。这样可以让客户端代码更加灵活,同时保持实现的独立性。工厂方法

    2024年02月06日
    浏览(41)
  • 创建型模式--2.简单工厂模式【人造恶魔果实工厂1】

    在海贼王中,作为原王下七武海之一的多弗朗明哥,可以说是新世界最大的流氓头子,拥有无上的权利和无尽的财富。他既是德雷斯罗萨国王又是地下世界的中介,控制着世界各地的诸多产业,人造恶魔果实工厂就是其中之一。 人造恶魔果实的最大买家是四皇之一的 凯多 ,

    2024年04月12日
    浏览(40)
  • 创建型模式-抽象工厂模式

    在抽象工厂模式中,接口是负责创建一个相关对象的工厂,不需要显式指定它们的类。每个生成的工厂都能按照工厂模式提供对象。 抽象工厂模式提供了一种创建一系列相关或相互依赖对象的接口,而无需指定具体实现类。通过使用抽象工厂模式,可以将客户端与具体产品的

    2024年02月11日
    浏览(34)
  • 【创建型模式】抽象工厂模式

    一、抽象工厂模式概述          抽象工厂模式定义 : 提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。 模式动机 : 1.当系统提供的工厂生产的具体产品并不是一个简单的对象,而是多个位于不同产品等级结构、属于不同类型的具体产品时就可

    2024年04月25日
    浏览(43)
  • 【创建者模式】工厂模式

    根据百科的定义,工厂模式是“工厂是用于创建其他对象的对象”。 以咖啡店为例,设计一个咖啡类Coffee,并定义其两个子类(美式咖啡AmericanCoffee和拿铁咖啡LatteCoffee);再设计一个咖啡店类CoffeeStore,咖啡店具有点咖啡的功能。 在上面的示例中,我们没有使用任何模式并

    2023年04月11日
    浏览(70)
  • [设计模式]创建型模式-简单工厂模式

    简单工厂模式又称为静态工厂模式,属于创建型模式,但不属于GOF23设计模式。由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。 简单工厂适用场景:工厂类负责创建的对象比较少;客户

    2024年02月20日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包