熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

基於SPRING的應用增加簡單規則引擎

2013-11-23 20:21:04  來源: Java開源技術 

  摘要
  
  這篇文章解釋了在JEE應用中規則引擎及聲明性業務邏輯的優點並且描述如何為流行的Spring框架開發簡單的規則引擎此文需要讀者對Spring有基本的了解
  
  任何大一點的軟件項目都包含了許多叫做業務邏輯的東西業務邏輯的准確描述還是有爭議的在為典型應用軟件的生成的大量代碼中到處都是為如訂單處理武器控制系統圖形繪制等功能工作的零碎代碼這些代碼與其他如處理持久化日志事務語言偏好框架特性及其他現代企業級應用有明顯不同
  
  業務邏輯通常與其他代碼塊緊密的混和在一起當重量級的侵入式框架(如EJB)被使用時區別業務邏輯與框架生成的代碼就變得非常困難
  
  有一個軟件需求在需求定義文檔很難准確描述卻擁有使軟件項目成功或失敗的能力適應性這是用來衡量軟件響應業務變更容易程度的標准
  
  現代企業要求響應快速及靈活他們對企業軟件也有同樣的要求可能你今天辛苦實現的業務規則在明天就被廢棄了而且要求你根據變更快速而准確的改變當你的包含業務邏輯的代碼隱藏在大量其他代碼中時修改就變得緩慢痛若且易出錯了
  
  在今天的企業級軟件中沒有奇跡比較流行的是規則引擎和各種業務過程管理(BPM)系統如果你看一下市場上的宣傳這類工具都承諾一件事保存在倉庫中的捕獲業務邏輯的聖杯能夠清晰的分離且由自己維護並隨時准備讓你現有的應用來調用
  
  雖然商業的規則引擎和BPM系統有許多優點但也有不少缺點最大的缺點就是價格通常很容易就達到位數另一個就是除了主要的行業規范和眾多記在紙上的標准外缺乏事實上的標准而且隨著越來越多的軟件項目采用敏捷輕量級的快速開發方法這些重量級的工具變得不符合潮流了
  
  在這篇文章中我們建立了一個簡單的規則引擎一方面平衡系統與業務邏輯的分離另一方面由於他基於目前流行的強大的JEE框架因而不需要承受商業軟件的復雜性與不協調性
  
  JEE世界中的Spring時代
  
  在企業級軟件的復雜性變得不能忍受及業務邏輯問題越來越重要時Spring及類似的框架產生了可以斷定Spring在以後很長一段時間內是企業級Java中的佼佼者Spring提供了很多工具及少量代碼約定使JEE的開發更面向對象更容易也更有趣
  
  Spring的核心是IoC原則這是一個奇特而超負荷的名字但包含下面的簡單想法
  
  ●功能代碼需要分開到更小的可管理片斷
  ●這些片斷是簡單的標准的JavaBean(簡單的Java類擁有但不包含全部的JavaBean規范)
  ●你不需要參與管理這些Bean(如創建銷毀設置依賴)
  ●相反Spring容器通過上下文定義來為你做這些(通常為XML文件格式)
  
  Spring也提供了很多其他特性如完整而強大的MVC框架簡便的JDBC開發包裝及其他框架但那些主題已經超出這篇幅文章的討論范圍
  
  在我描述需要什麼來創建基於SPRING應用的簡單規則引擎之前讓我們想一下為什麼這是一種好的想法
  
  規則引擎設計有兩點有趣的特性使其更有價值
  
  ●首先從應用領域分離了業務邏輯代碼
  ●其次可配置性意味著業務規則的定義及其使用的順序被存儲在應用的外部這樣就可以由規則創建人員來控制而不是應用的使用者或者開發人員了
  
  Spring為規則引擎提供了一個好的方法一個良好編碼的Spring應用的強組件化的設計會使你的代碼變成更小的可管理的分散片斷這樣就更易在Spring的上下文定義中配置
  
  繼續了解在規則引擎設計的需求與Spring設計提供的功能之間的結合點
  
  基於Spring的規則引擎的設計
  
  我們在Spring控制的JavaBean基礎上開始設計這裡我們叫做規則引擎組件我們來定義下面兩種我們可能需要的組件類型
  
  ●操作—在應用邏輯中確定用來做什麼的組件
  ●規則—在一系列行為的邏輯流中做出決定的組件
  
  我們都是面向對象設計的追隨者下面的基類建立了所有我們的組件需要通過參數被其他組件調用的基本功能
  
  public abstract class AbstractComponent {  public abstract void execute(Object arg) throws Exception; }
  
  當然基類是抽象的因為我們根本不需要這樣的實例
  
  AbstractAction的代碼擴展了基類來實現其他具體的操作
  
  public abstract class AbstractAction extends AbstractComponent {  private AbstractComponent nextStep;   public void execute(Object arg) throws Exception {   thisdoExecute(arg);   if(nextStep != null)     nextStepexecute(arg);  }   protected abstract void doExecute(Object arg) throws Exception;  public void setNextStep(AbstractComponent nextStep) {   thisnextStep = nextStep;  }  public AbstractComponent getNextStep() {   return nextStep;  }}
  
  你可以看到AbstractAction做兩件事首先他保存在規則引擎中被激活的下一個組件的定義其次在他的execute()方法中調用被具體類實現的doExecute()方法在doExecute()返回後如果存在下一個組件則調用他
  
  我們的AbstractRule也相當簡單
  
  public abstract class AbstractRule extends AbstractComponent {  private AbstractComponent positiveOutcomeStep;  private AbstractComponent negativeOutcomeStep;   public void execute(Object arg) throws Exception {   boolean outcome = makeDecision(arg);   if(outcome)     positiveOutcomeStepexecute(arg);   else     negativeOutcomeStepexecute(arg);  }  protected abstract boolean makeDecision(Object arg) throws Exception;
  
  // 為簡單起見positiveOutcomeStep和negativeOutcomeStep 的Getters 和 setters均已省略
  
  在其execute()方法中AbstractAction調用由子類實現的makeDecision()方法然後根據方法的返回值調用組件定義的肯定或否定結果的方法
  
  在我們介紹了SpringRuleEngine類後我們的設計就基本完成了
  
  public class SpringRuleEngine {   private AbstractComponent firstStep;   public void setFirstStep(AbstractComponent firstStep) {   thisfirstStep = firstStep;  }   public void processRequest(Object arg) throws Exception {   firstStepexecute(arg);  }  }
  
  這就是我們規則引擎主類的全部定義第一個業務邏輯中的組件及開始執行的方法
  
  但是請稍等在哪裡綁定我們的類使之可以工作呢?下面你就可以看到如何利用Spring來幫助我們完成工作的方法了
  
  在操作中的基於Spring的規則引擎
  
  讓我們看一下這個框架如何工作的具體實例吧想象下面的用例我們需要開發負責貸款申請的應用程序我們需要滿足下面的條件
  
  ●檢查應用的完整性否則駁回
  ●檢查應用是否來自我們授權處理業務的應用
  ●檢查申請者的月收支比是否滿足我們的要求
  ●輸入的申請通過我們不知道實現細節的持久服務被存儲在數據庫中我們只知道他的接口(可能這個開發被外包到印度了)
  ●業務規則是可以改變的這也是為什麼需要規則引擎的設計了
  
  首先設計一個表示貸款申請的類
  
  public class LoanApplication {   public static final String INVALID_STATE = Sorry we are not doing business in your state;  public static final String INVALID_INCOME_EXPENSE_RATIO = Sorry we cannot provide the loan given this expense/income ratio;  public static final String APPROVED = Your application has been approved;  public static final String INSUFFICIENT_DATA = You did not provide enough information on your application;  public static final String INPROGRESS = in progress;   public static final String[] STATUSES =    new String[] {     INSUFFICIENT_DATA INVALID_INCOME_EXPENSE_RATIO INVALID_STATE APPROVED INPROGRESS   };  private String firstName;  private String lastName;  private double income;  private double expences;  private String stateCode;  private String status;   public void setStatus(String status) {   if(!ArraysasList(ntains(status))     throw new IllegalArgumentException(invalid status: + status);   thisstatus = status;  }// 其他getters and setters已被省略}
  
  我們使用的持久服務擁有如下接口
  
  public interface LoanApplicationPersistenceInterface {  public void recordApproval(LoanApplication application) throws Exception;  public void recordRejection(LoanApplication application) throws Exception;  public void recordIncomplete(LoanApplication application) throws Exception;}
  
  我們迅速開發一個什麼也不做只是用來滿足接口約定的MockLoanApplicationPersistence類來欺騙接口
  
  我們使用下面的SpringRuleEngine類的子類來加載Spring上下文並開始處理
  
  public class LoanProcessRuleEngine extends SpringRuleEngine {  public
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28349.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.