【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 }
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

相关推荐