Drools

Drools

简介

Drools 是一个业务规则管理系统(Business Rules Management System,BRMS) 解决方案。主要目的是将复杂的业务逻辑抽离出来,将其编辑成为配置文件便于后期进行修改。

使用方式

首先需要引入相关包:

1
2
3
4
5
6
7
8
9
10
11
12
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
annotationProcessor 'org.projectlombok:lombok'
implementation 'org.drools:drools-core:9.44.0.Final'
implementation 'org.kie:kie-spring:7.74.1.Final'
implementation 'org.kie:kie-api:9.44.0.Final'
implementation 'org.drools:drools-compiler:9.44.0.Final'
implementation 'org.drools:drools-mvel:9.44.0.Final'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

编写业务类:

1
2
3
4
5
6
7
8
9
10
11
12
import lombok.Data;

@Data
public class Fare {
private Long nightSurcharge = 0L;
private Long rideFare = 0L;

public Long getTotalFare() {
return nightSurcharge + rideFare;
}

}
1
2
3
4
5
6
7
import lombok.Data;

@Data
public class TaxiRide {
private Boolean isNightSurcharge;
private Long distanceInMile;
}

编写规则文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import com.example.xxx.model.TaxiRide
import com.example.xxx.model.Fare
import java.util.*

global com.example.xxx.model.Fare rideFare;
dialect "mvel"

rule "Calculate Taxi Fare - Scenario 1"
when
taxiRideInstance:TaxiRide(isNightSurcharge == false && distanceInMile < 10);
then
rideFare.setNightSurcharge(0L);
rideFare.setRideFare(70L);
end

编写配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieModule;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.example.xxx.service")
public class TaxiFareConfiguration {

public static final String drlFile = "TAXI_FARE_RULE.drl";

@Bean
public KieContainer kieContainer() {
KieServices kieServices = KieServices.Factory.get();

KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
kieFileSystem.write(ResourceFactory.newClassPathResource(drlFile));
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
KieModule kieModule = kieBuilder.getKieModule();

return kieServices.newKieContainer(kieModule.getReleaseId());
}

}

编写服务类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class TaxiFareCalculatorService {

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

@Autowired
private KieContainer kContainer;

public Long calculateFare(TaxiRide taxiRide, Fare rideFare) {
KieSession kieSession = kContainer.newKieSession();
kieSession.setGlobal("rideFare", rideFare);
kieSession.insert(taxiRide);
kieSession.fireAllRules();
kieSession.dispose();
LOGGER.debug("!! RIDE FARE !! " + rideFare.getTotalFare());
return rideFare.getTotalFare();
}
}

之后即可使用测试类进行测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@SpringBootTest
class ApplicationTests {

@Resource
private TaxiFareCalculatorService taxiFareCalculatorService;

@Test
void contextLoads() {
}

@Test
public void whenNightSurchargeFalseAndDistLessThan10_thenFixWithoutNightSurcharge() {
TaxiRide taxiRide = new TaxiRide();
taxiRide.setIsNightSurcharge(false);
taxiRide.setDistanceInMile(9L);
Fare rideFare = new Fare();
Long totalCharge = taxiFareCalculatorService.calculateFare(taxiRide, rideFare);

assertNotNull(totalCharge);
assertEquals(Long.valueOf(70), totalCharge);
}
}

参考资料

项目官网

官方手册

Drools Spring Integration


Drools
https://wangqian0306.github.io/2023/drools/
作者
WangQian
发布于
2023年11月8日
许可协议