easy rules 사용 [8] jeasy API(Controller 추가 있음) 예시
예시 [1] 단일 조건
이전에 작성한 easy rules 사용 [1] 게시물의 예시를 작성해보겠다. 메인이 되는 class를 다음과 같이 수정하겠다. 이번 예시에서는 다른 controller의 method를 가져다 쓰는 테스트를 진행하기에, main method 상단에 test method를 생성하도록 하겠다. 규칙을 정의하는 controller를 import 하는 것도 잊지말자.
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;
import easyRulesTest.controller.EasyRulesController;
// Test Method
public static void testMethod(String test) {
System.out.println("\t :::::: test method : " + test);
}
// Main Method
public class Launcher {
public static void main(String... args) {
// facts 생성
Facts facts = new Facts();
facts.put("position", true);
// rules 생성
Rules rules = new Rules();
rules.register(new EasyRulesController());
// rules engine 생성
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
}
}
다음으로, 규칙을 정의하는 EasyRulesController.java class 파일을 수정하도록 하겠다.
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import easyRulesTest.controller.Launcher;
@Rule(name = "EasyRulesController", description = "EasyRulesTest", priority = 1)
public class EasyRulesController {
@Condition
public boolean positionCheck(@Fact("position") boolean position) {
return position;
}
@Action
public void takeAnUmbrella() {
String test = "Position Check Complete !";
Launcher launcher = new Launcher();
launcher.testMethod(test);
}
}
해당 project를 실행하면, 다음과 같은 console 화면을 확인할 수 있다.
예시 [2] 다중 조건
메인이 되는 class에 대해 rule 추가에 대한 수정이 필요하다. 이후 규칙을 정의하는 EasyRulesController.java class 파일을 추가로 만들어주면 된다. 메인이 되는 class를 다음과 같이 수정하자. 규칙을 정의하는 controller들을 import 하는 것도 잊지말자.
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.api.RulesEngine;
import org.jeasy.rules.core.DefaultRulesEngine;
import easyRulesTest.controller.EasyRulesController;
import easyRulesTest.controller.EasyRulesController2;
import easyRulesTest.controller.EasyRulesController3;
// Test Method
public static void testMethod(String test) {
System.out.println("\t :::::: test method : " + test);
}
// Main Method
public class Launcher {
public static void main(String... args) {
// facts 생성
Facts facts = new Facts();
facts.put("position", true);
facts.put("department", true);
facts.put("authLevel", 3);
// rules 생성
Rules rules = new Rules();
rules.register(new EasyRulesController());
rules.register(new EasyRulesController2());
rules.register(new EasyRulesController3());
// rules engine 생성
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
}
}
다음으로, 규칙을 정의하는 EasyRulesController.java class 파일을 추가하도록 하겠다. 필자는 기존의 controller를 복사 후 붙여넣어, 변수 및 이름만 변경하여 사용하였다. @Rule annotation에 priority 속성을 지정하여 순위를 매겨주는 것을 잊지말자. 그렇지 않으면 제일 마지막 controller만 rule로 실행된다.
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import easyRulesTest.controller.Launcher;
@Rule(name = "EasyRulesController", description = "EasyRulesTest", priority = 2)
public class EasyRulesController2 {
@Condition
public boolean departmentCheck(@Fact("department") boolean department) {
return department;
}
@Action
public void checkComplete() {
String test = "Department Check Complete !";
Launcher launcher = new Launcher();
launcher.testMethod(test);
}
}
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Fact;
import org.jeasy.rules.annotation.Rule;
import easyRulesTest.controller.Launcher;
@Rule(name = "EasyRulesController", description = "EasyRulesTest", priority = 3)
public class EasyRulesController3 {
@Condition
public boolean authLevelCheck(@Fact("authLevel") int authLevel) {
boolean authLevel_B = false;
if(authLevel > 2) {
authLevel_B = true;
return authLevel_B;
} else {
return authLevel_B;
}
}
@Action
public void checkComplete() {
String test = "AuthLevel Check Complete !";
Launcher launcher = new Launcher();
launcher.testMethod(test);
}
}
해당 project를 실행하면, 다음과 같은 console 화면을 확인할 수 있다.
보다시피, @Rule annotation에 설정한 priority(순위)에 따라서, 매개변수를 포함한 다른 controller의 method를 호출할 수 있는 action값을 확인할 수 있다.
TIP
사실 필자는 YML 방식 및 MVEL Rule이 사용하기에 간편하여, 괜찮은 친구들이라 생각하였다. 하지만 YML 방식는 method 호출이 불가능하다는 단점이 확실하게 존재하였고, MVEL Rule도 테스트 결과 사용하기 어렵거나 혹은 불가능한 것으로 생각된다. (YML 방식의 경우 지원하지 않음을 docs에서 확인할 수 있었다. MVEL Rule의 경우 docs 및 여러 해외 커뮤니티에서도 지원한다는 내용을 확인할 수 없었다)
easy rules의 기본적인 형태 사용에 있어 가장 큰 장점으로, 필자는 method 호출을 꼽을 것이다. 다음으로는 @Condition 조건에 대한 custom의 자유성을 꼽을 것이다. return 값은 어쩔 수 없이 boolean type으로 줘야겠지만(그렇지 않을 시, IllegalArgumentException이 발생한다), parameter 값으로 받아온 데이터를 어떻게 사용할 지는 사용자의 마음에 달려있다.
easy rules를 사용하는 독자들은, 수 많은 if문 대신 rule engine을 선택한 것에 대한 높은 효율성을 느껴보았으면 좋겠다. 물론 규격화되어있는 전제 조건이 필요하겠지만...
[ 출처 ]
Easy Rules 사용법 : https://www.baeldung.com/java-rule-engines