【java规则引擎】之Drools引擎中模拟ReteooStatefulSession内部设计结构
该片文章只是抽取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 }
二:模拟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 }
三:模拟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 }
四:模拟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 }
五:模拟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 }
六:模拟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 }
七:模拟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 }
八:模拟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 }