国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

基于SPRING的應(yīng)用增加簡(jiǎn)單規(guī)則引擎

2019-11-18 13:00:21
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

  摘要
  
  這篇文章解釋了在J2EE應(yīng)用中規(guī)則引擎及聲明性業(yè)務(wù)邏輯的優(yōu)點(diǎn),并且描述如何為流行的SPRing框架開發(fā)簡(jiǎn)單的規(guī)則引擎。此文需要讀者對(duì)Spring有基本的了解。
  
  任何大一點(diǎn)的軟件項(xiàng)目都包含了許多叫做業(yè)務(wù)邏輯的東西。業(yè)務(wù)邏輯的準(zhǔn)確描述還是有爭(zhēng)議的。在為典型應(yīng)用軟件的生成的大量代碼中,到處都是為如訂單處理、武器控制系統(tǒng)、圖形繪制等功能工作的零碎代碼。這些代碼與其他如處理持久化、日志、事務(wù)、語(yǔ)言偏好、框架特性及其他現(xiàn)代企業(yè)級(jí)應(yīng)用有明顯不同。
  
  業(yè)務(wù)邏輯通常與其他代碼塊緊密的混和在一起。當(dāng)重量級(jí)的侵入式框架(如EJB)被使用時(shí),區(qū)別業(yè)務(wù)邏輯與框架生成的代碼就變得非常困難。
  
  有一個(gè)軟件需求在需求定義文檔很難準(zhǔn)確描述,卻擁有使軟件項(xiàng)目成功或失敗的能力:適應(yīng)性,這是用來(lái)衡量軟件響應(yīng)業(yè)務(wù)變更輕易程度的標(biāo)準(zhǔn)。
  
  現(xiàn)代企業(yè)要求響應(yīng)快速及靈活,他們對(duì)企業(yè)軟件也有同樣的要求。可能你今天辛勞實(shí)現(xiàn)的業(yè)務(wù)規(guī)則在明天就被廢棄了而且要求你根據(jù)變更快速而準(zhǔn)確的改變。當(dāng)你的包含業(yè)務(wù)邏輯的代碼隱藏在大量其他代碼中時(shí),修改就變得緩慢、痛若且易出錯(cuò)了。
  
  在今天的企業(yè)級(jí)軟件中沒(méi)有奇跡,比較流行的是規(guī)則引擎和各種業(yè)務(wù)過(guò)程治理(BPM)系統(tǒng)。假如你看一下市場(chǎng)上的宣傳,這類工具都承諾一件事:保存在倉(cāng)庫(kù)中的捕捉業(yè)務(wù)邏輯的圣杯能夠清楚的分離且由自己維護(hù),并隨時(shí)預(yù)備讓你現(xiàn)有的應(yīng)用來(lái)調(diào)用。
  
  雖然商業(yè)的規(guī)則引擎和BPM系統(tǒng)有許多優(yōu)點(diǎn),但也有不少缺點(diǎn)。最大的缺點(diǎn)就是價(jià)格,通常很輕易就達(dá)到7位數(shù)。另一個(gè)就是除了主要的行業(yè)規(guī)范和眾多記在紙上的標(biāo)準(zhǔn)外缺乏事實(shí)上的標(biāo)準(zhǔn)。而且隨著越來(lái)越多的軟件項(xiàng)目采用靈敏、輕量級(jí)的快速開發(fā)方法,這些重量級(jí)的工具變得不符合潮流了。
  
  在這篇文章中,我們建立了一個(gè)簡(jiǎn)單的規(guī)則引擎,一方面平衡系統(tǒng)與業(yè)務(wù)邏輯的分離,另一方面由于他基于目前流行的強(qiáng)大的J2EE框架因而不需要承受商業(yè)軟件的復(fù)雜性與不協(xié)調(diào)性。
  
  J2EE世界中的Spring時(shí)代
  
  在企業(yè)級(jí)軟件的復(fù)雜性變得不能忍受及業(yè)務(wù)邏輯問(wèn)題越來(lái)越重要時(shí),Spring及類似的框架產(chǎn)生了。可以斷定Spring在以后很長(zhǎng)一段時(shí)間內(nèi)是企業(yè)級(jí)java中的佼佼者。Spring提供了很多工具及少量代碼約定使J2EE的開發(fā)更面向?qū)ο螅p易也更有趣。
  
  Spring的核心是IoC原則,這是一個(gè)奇異而超負(fù)荷的名字,但包含下面的簡(jiǎn)單想法:
  
  ●功能代碼需要分開到更小的可治理片斷
  ●這些片斷是簡(jiǎn)單的,標(biāo)準(zhǔn)的JavaBean(簡(jiǎn)單的Java類擁有但不包含全部的JavaBean規(guī)范)
  ●你不需要參與治理這些Bean(如創(chuàng)建、銷毀、設(shè)置依靠)
  ●相反Spring容器通過(guò)上下文定義來(lái)為你做這些(通常為xml文件格式)
  
  Spring也提供了很多其他特性,如完整而強(qiáng)大的MVC框架,簡(jiǎn)便的JDBC開發(fā)包裝及其他框架。但那些主題已經(jīng)超出這篇幅文章的討論范圍。
  
  在我描述需要什么來(lái)創(chuàng)建基于SPRING應(yīng)用的簡(jiǎn)單規(guī)則引擎之前,讓我們想一下為什么這是一種好的想法。
  
  規(guī)則引擎設(shè)計(jì)有兩點(diǎn)有趣的特性使其更有價(jià)值:
  
  ●首先,從應(yīng)用領(lǐng)域分離了業(yè)務(wù)邏輯代碼。
  ●其次,可配置性意味著業(yè)務(wù)規(guī)則的定義及其使用的順序被存儲(chǔ)在應(yīng)用的外部,這樣就可以由規(guī)則創(chuàng)建人員來(lái)控制而不是應(yīng)用的使用者或者開發(fā)人員了。
  
  Spring為規(guī)則引擎提供了一個(gè)好的方法。一個(gè)良好編碼的Spring應(yīng)用的強(qiáng)組件化的設(shè)計(jì)會(huì)使你的代碼變成更小的、可治理的分散片斷,這樣就更易在Spring的上下文定義中配置。
  
  繼續(xù)了解在規(guī)則引擎設(shè)計(jì)的需求與Spring設(shè)計(jì)提供的功能之間的結(jié)合點(diǎn)。
  
  基于Spring的規(guī)則引擎的設(shè)計(jì)
  
  我們?cè)赟pring控制的JavaBean基礎(chǔ)上開始設(shè)計(jì),這里我們叫做規(guī)則引擎組件。我們來(lái)定義下面兩種我們可能需要的組件類型:
  
  ●操作—在應(yīng)用邏輯中確定用來(lái)做什么的組件
  ●規(guī)則—在一系列行為的邏輯流中做出決定的組件
  
  我們都是面向?qū)ο笤O(shè)計(jì)的追隨者,下面的基類建立了所有我們的組件需要通過(guò)參數(shù)被其他組件調(diào)用的基本功能:
  
  public abstract class AbstractComponent {  public abstract void execute(Object arg) throws Exception; }
  
  當(dāng)然基類是抽象的因?yàn)槲覀兏静恍枰@樣的實(shí)例。
  
  AbstractAction的代碼擴(kuò)展了基類來(lái)實(shí)現(xiàn)其他具體的操作:
  
  public abstract class AbstractAction extends AbstractComponent {  private AbstractComponent nextStep;   public void execute(Object arg) throws Exception {   this.doExecute(arg);   if(nextStep != null)     nextStep.execute(arg);  }   protected abstract void doExecute(Object arg) throws Exception;  public void setNextStep(AbstractComponent nextStep) {   this.nextStep = nextStep;  }  public AbstractComponent getNextStep() {   return nextStep;  }}
  
  你可以看到,AbstractAction做兩件事:首先他保存在規(guī)則引擎中被激活的下一個(gè)組件的定義;其次在他的execute()方法中,調(diào)用被具體類實(shí)現(xiàn)的doExecute()方法,在doExecute()返回后,假如存在下一個(gè)組件則調(diào)用他。
  
  我們的AbstractRule也相當(dāng)簡(jiǎn)單:
  
  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)     positiveOutcomeStep.execute(arg);   else     negativeOutcomeStep.execute(arg);  }  protected abstract boolean makeDecision(Object arg) throws Exception;
  
  // 為簡(jiǎn)單起見(jiàn),positiveOutcomeStep和negativeOutcomeStep 的Getters 和 setters均已省略
  
  在其execute()方法中,AbstractAction調(diào)用由子類實(shí)現(xiàn)的makeDecision()方法,然后根據(jù)方法的返回值,調(diào)用組件定義的肯定或否定結(jié)果的方法。
  
  在我們介紹了SpringRuleEngine類后我們的設(shè)計(jì)就基本完成了:
  
  public class SpringRuleEngine {   private AbstractComponent firstStep;   public void setFirstStep(AbstractComponent firstStep) {   this.firstStep = firstStep;  }   public void processRequest(Object arg) throws Exception {   firstStep.execute(arg);  }  }
  
  這就是我們規(guī)則引擎主類的全部:定義第一個(gè)業(yè)務(wù)邏輯中的組件及開始執(zhí)行的方法。
  
  但是請(qǐng)稍等,在哪里綁定我們的類使之可以工作呢?下面你就可以看到如何利用Spring來(lái)幫助我們完成工作的方法了。
  
  在操作中的基于Spring的規(guī)則引擎
  
  讓我們看一下這個(gè)框架如何工作的具體實(shí)例吧。想象下面的用例:我們需要開發(fā)負(fù)責(zé)貸款申請(qǐng)的應(yīng)用程序。我們需要滿足下面的條件:
  
  ●檢查應(yīng)用的完整性否則駁回
  ●檢查應(yīng)用是否來(lái)自我們授權(quán)處理業(yè)務(wù)的應(yīng)用。
  ●檢查申請(qǐng)者的月收支比是否滿足我們的要求。
  ●輸入的申請(qǐng)通過(guò)我們不知道實(shí)現(xiàn)細(xì)節(jié)的持久服務(wù)被存儲(chǔ)在數(shù)據(jù)庫(kù)中,我們只知道他的接口(可能這個(gè)開發(fā)被外包到印度了)
  ●業(yè)務(wù)規(guī)則是可以改變的,這也是為什么需要規(guī)則引擎的設(shè)計(jì)了。
  
  首先,設(shè)計(jì)一個(gè)表示貸款申請(qǐng)的類:
  
  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(!Arrays.asList(STATUSES).contains(status))     throw new IllegalArgumentException("invalid status:" + status);   this.status = status;  }// 其他getters and setters已被省略}
  
  我們使用的持久服務(wù)擁有如下接口:
  
  public interface LoanApplicationPersistenceInterface {  public void recordApproval(LoanApplication application) throws Exception;  public void recordRejection(LoanApplication application) throws Exception;  public void recordIncomplete(LoanApplication application) throws Exception;}
  
  我們迅速開發(fā)一個(gè)什么也不做只是用來(lái)滿足接口約定的MockLoanApplicationPersistence類來(lái)欺騙接口。
  
  我們使用下面的SpringRuleEngine類的子類來(lái)加載Spring上下文并開始處理:
  
  public class LoanProcessRuleEngine extends SpringRuleEngine {  public

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 抚顺市| 南丰县| 南川市| 封开县| 青州市| 米林县| 呼玛县| 额尔古纳市| 平和县| 沾化县| 定西市| 陇西县| 安图县| 化隆| 福贡县| 铜川市| 全州县| 繁昌县| 志丹县| 专栏| 卢氏县| 苗栗市| 儋州市| 尖扎县| 内丘县| 宜章县| 贵港市| 绥中县| 五大连池市| 无为县| 大埔区| 西乌| 筠连县| 商河县| 抚顺县| 崇明县| 育儿| 勐海县| 山阳县| 秦安县| 噶尔县|