【java规则引擎】之Drools引擎中模拟ReteooStatefulSession内部设计结构
分类:
IT文章
•
2023-11-20 20:48:18
该片文章只是抽取drools中java代码实现的一些代码结构,帮助我们理解drools是如何实现rete算法的。
该部分只是抽取ReteooStatefulSession工作过程中的代码架构
利用了多线程设计的一个代理模式(自己起的名字)
利用了23中设计模式中的命令模式
一:模拟drools中ReteooStatefulSession的实现对象StatefulSession
1 package com.nonbankcard.drools.module;
2
3
4
5 /**
6 *
7 * 在当前的设计模式中:
8 * (1)它作为规则匹配的发起者,它内部引用了执行器代理,执行器
9 * (2)执行器引用了它
10 * (3)它提交一个命令,交给执行器代理,执行器代理交给执行器线程异步处理
11 *
12 *在drools中
13 * (1)把规则库理解成一个数据库,规则匹配的入口,类比jdbc的一个链接对象
14 * (2)它引用ruleBase(规则库)
15 * (3)RuleBase(规则库)里也引用了它
16 * @author sxf
17 *
18 */
19 public class StatefulSession implements WorkingMemory{
20
21 /**
22 * 业务执行器的代理
23 */
24 private DefaultExecutorService executorService;
25
26 public StatefulSession(DefaultExecutorService executorService ){
27 this.executorService=executorService;
28 }
29
30
31
32 /**
33 * 异步插入命令,执行命令
34 * @param object
35 * @return
36 */
37 public Future asyncInsert(final Command command) {
38 this.executorService.submit(command);
39 return (Future) command;
40 }
41
42
43 /**
44 * 是否得到执行规则
45 */
46 @Override
47 public String isGetRule() {
48
49 return "我得到了执行规则,name=[sxf]";
50 }
51
52
53
54
55 }
View Code
二:模拟drools中DefaultExecutorService的实现对象DefaultExecutorService
1 package com.nonbankcard.drools.module;
2 /**
3 * 业务命令执行代理
4 * @author sxf
5 *
6 */
7 public class DefaultExecutorService {
8
9 //线程类
10 private Thread thread;
11
12 /**
13 * 业务命令真正的执行者线程
14 *
15 */
16 private CommandExecutor commandExecutor;
17 /**
18 * 命令执行器是否已经开始执行
19 */
20 private boolean runing;
21
22 /**
23 * 空构造
24 */
25 public DefaultExecutorService(){
26
27 }
28
29 /**
30 * 构造函数
31 */
32 public DefaultExecutorService(CommandExecutor commandExecutor){
33 this.commandExecutor=commandExecutor;
34 }
35
36
37
38 /**
39 * (1)给业务命令执行代理提交命令
40 * (2)其实内部是交给真正的线程执行(CommandExecutor)
41 * @param command
42 * @return
43 */
44 public Future submit(Command command){
45 if(!runing){
46 //启动命令执行器
47 startUp();
48 }
49
50 //交给真正的命令执行器执行
51 return (Future) this.commandExecutor.submint(command);
52 }
53
54
55 /**
56 * 启动真正的命令执行器
57 */
58 public void startUp(){
59 //启动命令执行器的线程
60 this.thread=new Thread(this.commandExecutor);
61 this.thread.start();
62 //将命令执行器的状态设置为启动
63 this.runing=true;
64 }
65
66
67 public void shutDown() {
68 //关闭命令执行器的线程
69 this.commandExecutor.shutDown();
70 //关闭当前命令执行代理的标识
71 this.runing = false;
72 //释放真正命令执行器的引用,让线程体被Gc回收
73 this.thread = null;
74 }
75
76 public CommandExecutor getCommandExecutor() {
77 return commandExecutor;
78 }
79
80 public void setCommandExecutor(CommandExecutor commandExecutor) {
81 this.commandExecutor = commandExecutor;
82 }
83
84
85
86
87 }
View Code
三:模拟drools中CommandExecutor的实现对象CommandExecutor
1 package com.nonbankcard.drools.module;
2
3 import java.util.concurrent.BlockingQueue;
4
5 /**
6 *业务命令执行器
7 * @author sxf
8 *
9 */
10 public class CommandExecutor implements Runnable {
11
12 /**
13 * 阻塞队列
14 */
15 private BlockingQueue<Command> queue;
16
17 /**
18 * 这个引用,就是statefulSession的引用
19 */
20 private WorkingMemory WorkingMemory;
21
22 /**
23 * 命令执行的标识
24 */
25 private boolean running;
26
27
28
29 public CommandExecutor(StatefulSession session){
30 this.WorkingMemory=session;
31 }
32
33 /**
34 * 给命令执行器提交一个命令
35 * @param command
36 */
37 public Future submint(Command command){
38 //把命令放到队列里,等待线程执行
39 this.queue.offer(command);
40 //此处在下一个版本升级的时候,返回这个命令。
41 //可以从这个命令里获取命令的执行结果
42 return (Future) command;
43 }
44
45
46 /**
47 * 业务命令执行器的线程体
48 */
49 @Override
50 public void run() {
51 this.running=true;
52
53 while(this.running){
54 try {
55 //从队列中取出命令
56 Command command=queue.take();
57 //执行命令,传入的就是statefulSession
58 command.execute(WorkingMemory);
59 } catch (InterruptedException e) {
60 e.printStackTrace();
61 }
62 }
63
64 }
65
66 /**
67 * 关闭命令执行线程
68 */
69 public void shutDown(){
70 this.running=false;
71 }
72
73 }
View Code
四:模拟drools中Command的实现对象Command
1 package com.nonbankcard.drools.module;
2 /**
3 * 命令接口
4 * @author sxf
5 *
6 */
7 public interface Command {
8
9 /**
10 * 执行命令的接口定义
11 * @param workingMemory==>这里传的就是StatefulSession
12 */
13 public void execute(WorkingMemory workingMemory);
14 }
View Code
五:模拟drools中Future的实现对象Future
1 package com.nonbankcard.drools.module;
2 /**
3 * 命令执行结果查询
4 * @author sxf
5 *
6 */
7 public interface Future {
8 /**
9 * 命令是否执行
10 * @return
11 */
12 public boolean isDone();
13 /**
14 * 获取命令执行结果
15 * @return
16 */
17 public Object getDoneResult();
18 /**
19 * 获取命令执行的异常信息
20 * @return
21 */
22 public Exception getDoneingException();
23 }
View Code
六:模拟drools中FireAllRules的实现对象FireRuleCommand
1 package com.nonbankcard.drools.module;
2 /**
3 * 激活规则的命令
4 * @author sxf
5 *
6 */
7 public class FireRuleCommand implements Command,Future{
8 /**
9 * 命令是否被执行
10 */
11 private volatile boolean done;
12 /**
13 * 命令执行过程中的异常
14 */
15 private Exception e;
16 /**
17 * 命令的执行结果
18 */
19 private Object object;
20
21
22 /**
23 * 执行命令
24 */
25 @Override
26 public void execute(WorkingMemory workingMemory) {
27 try {
28 //模拟执行命令
29 Thread.sleep(1000L);
30 object=workingMemory.isGetRule();
31 } catch (Exception e) {
32 //给命令赋值执行异常
33 this.e=e;
34 }
35 //表示命令已经执行
36 this.done=done;
37 }
38
39
40 /**
41 * 命令是否执行
42 */
43 @Override
44 public boolean isDone() {
45 return this.done;
46 }
47
48 /**
49 * 获取命令的执行结果
50 */
51 @Override
52 public Object getDoneResult() {
53 return this.object;
54 }
55
56 /**
57 * 获取命令执行过程中的异常
58 */
59 @Override
60 public Exception getDoneingException() {
61 return this.e;
62 }
63
64
65
66 }
View Code
七:模拟drools中WorkingMemory的实现对象WorkingMemory
1 package com.nonbankcard.drools.module;
2 /**
3 * 【1】statefulSession实现的接口
4 * 【2】在drools里该接口的作用
5 * (1)定义了关于获取最终fact匹配上规则要执行的议程
6 * (2)定义了激活规则的方法
7 * (3)定义了匹配过程中需要执行的Handler等内容
8 * @author sxf
9 *
10 */
11 public interface WorkingMemory {
12
13 /**
14 * 是否得到匹配规则
15 * @return
16 */
17 public String isGetRule();
18
19 }
View Code
八:模拟drools中ReteooStatefulSession启动的实现过程,该过程隐藏在drools中的org.drools.reteoo.ReteooRuleBase.newStatefulSession()方法中
1 package com.nonbankcard.drools.module;
2 /**
3 * statefulSession的启动过程
4 * @author sxf
5 *
6 */
7 public class StateFulSessionTest {
8
9 public static void main(String[] args) {
10
11
12 //生成一个业务命令执行代理
13 DefaultExecutorService executorService=new DefaultExecutorService();
14
15 //生成一个statefulSession
16 StatefulSession session=new StatefulSession(executorService);
17
18 //生成真正执行命令的线程体
19 CommandExecutor commandExecutor=new CommandExecutor(session);
20
21 //将真正执行命令的线程体放入业务命令执行代理
22 executorService.setCommandExecutor(commandExecutor);
23
24
25 //sesssion初始化完毕。可以开始做规则匹配的任务了
26 //初始化一个命令
27 FireRuleCommand fireCommand=new FireRuleCommand();
28
29 //session可以异步添加命令
30 Future future=(Future) session.asyncInsert(fireCommand);
31
32 }
33
34 }
View Code