본문 바로가기

소프트웨어-이야기/프로그래밍 언어와 프레임워크

[Rule Engine] 비즈니스 규칙 엔진

비즈니스 규칙 엔진이란?

비즈니스 규칙 엔진이란, 어떤 조건에 따라 액션을 유발하는 규칙이 있는 비즈니스 기능을 구현할 때 사용하는 프로그램이다. 

비즈니스 규칙 엔진의 요구사항은 크게 4가지로 나뉜다.

  • 팩트 : 규칙이 확인할 수 있는 정보
  • 액션 : 수행하려는 동작
  • 조건 : 액션을 언제 발생시킬지 지정
  • 규칙 : 실행하려는 비즈니스 규칙을 지정
    • 보통 팩트/액션/조건을 한 그룹으로 묶어서 규칙으로 만든다.

비즈니스 규칙 엔진 구현 방법은 다음과 같다.

Diagram

Code

Class

@FunctionalInterface
public interface Action {

  void execute(Facts facts);
}

 

@FunctionalInterface
public interface Condition {
  boolean evaluate(Facts facts);
}

 

interface Rule {
  void perform(Facts facts);
}

 

class DefaultRule implements Rule {
  private final Condition condition;
  private final Action action;

  public DefaultRule(final Condition condition, final Action action) {
    this.condition = condition;
    this.action = action;
  }

  @Override
  public void perform(Facts facts) {
    if(condition.evaluate(facts)) {
      action.execute(facts);
    }
  }
}

 

public class RuleBuilder {
  private Condition condition;

  private RuleBuilder(final Condition condition) {
    this.condition = condition;
  }

  public static RuleBuilder when(final Condition condition) {
    return new RuleBuilder(condition);
  }

  public Rule then(final Action action) {
    return new DefaultRule(condition, action);
  }

}

 

import java.util.HashMap;
import java.util.Map;

public class Facts {

  private final Map<String, String> facts = new HashMap<>();

  public String getFact(final String name) {
    return this.facts.get(name);
  }

  public void addFact(final String name, final String value) {
    this.facts.put(name, value);
  }

}

 

import java.util.ArrayList;
import java.util.List;

public class BusinessRuleEngine {

  private final List<Rule> rules;
  private final Facts facts;

  public BusinessRuleEngine(final Facts facts) {
    this.rules = new ArrayList<>();
    this.facts = facts;
  }

  public void addRule(final Rule rule) {
    this.rules.add(rule);
  }

  public void run() {
    this.rules.forEach(rule -> rule.perform(facts));
  }

}

 

Client

final Rule ruleSendEmailToSalesWhenCEO = RuleBuilder
        .when(facts -> "CEO".equals(facts.getFact("jobTitle")))
        .then(facts -> {
          var name = facts.getFact("name");
          Mailer.sendEmail("sales@company.com", "Relevant customer: " + name);
        });
        
final facts = new Facts();
facts.addFact("name", "김복세");
facts.addFact("jobTitle", "CEO");

final BusinessRuleEngine businessRuleEngine = new BusinessRuleEngine(facts);
businessRuleEngine.addRule(ruleSendEmailToSalesWhenCEO);
businessRuleEngine.run();

기반 지식

 

 

참고

실전 자바 소프트웨어 개발 5장. 비즈니스 규칙 엔진

 

 classDiagram
      DefaultRule ..|>	Rule : Realization(실체화)
      BusinessRuleEngine-->Rule: Association(연관)
      BusinessRuleEngine-->Facts: Association(연관)
      DefaultRule-->Condition: Association(연관)
      DefaultRule-->Action: Association(연관)
      Action..> Facts: ependency(의존)
      Condition ..> Facts: Dependency(의존)
      DefaultRule ..>	Facts : Dependency(의존)
      RuleBuilder-->Condition: Association(연관)
      RuleBuilder..>Action: Association(연관)
      class Rule{
          +perform(Facts facts)
      }
      class Action{
          + execute(Facts facts)
      }
      class Condition{
          +bool evaluate(Facts facts)
      }
      
      class RuleBuilder{
           -Condition condition

          +when(Condition condition)
          + Rule then(Action action)
      }
      class DefaultRule{
           -Condition condition
           -Action action

          +perform(Facts facts)
      }
      class Facts{
           -Map<String, String> facts

          +String getFact(String name)
          +addFact(String name, String value)
      }
      class BusinessRuleEngine{
           - List<Rule> rules;
           - Facts facts;

          +addRule(Rule rule)
          +run()
      }