【java規則引擎】之Drools引擎中模擬ReteooStatefulSession內部設計結構

Love Lenka發表於2017-01-12

  該片文章只是抽取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

 

相關文章