王雁苓, 孫 利, 郭新辰, 呂學(xué)實(shí)
(1. 吉林省教育學(xué)院 教務(wù)處, 長春 130022; 2. 吉林廣播電視大學(xué), 長春 130022; 3. 東北電力大學(xué) 理學(xué)院, 吉林 吉林 132012; 4. 吉林省工商銀行 科技處, 長春 130022)
現(xiàn)代信息管理軟件采用定制開發(fā)的方法滿足用戶不斷變化的需求, 應(yīng)用字典技術(shù)是設(shè)計定制軟件開發(fā)平臺的關(guān)鍵技術(shù). 應(yīng)用字典模型的設(shè)計是把業(yè)務(wù)實(shí)體表的定義放到AD_Table和AD_Column數(shù)據(jù)庫表中, 其中AD_Table主要存儲業(yè)務(wù)實(shí)體表的表名(table name)信息, AD_Column存儲表字段(field)的主要屬性和顯示邏輯[1].
使用AD技術(shù)設(shè)計的數(shù)據(jù)庫邏輯上被劃分成兩部分: AD表和業(yè)務(wù)實(shí)體表. 業(yè)務(wù)實(shí)體表示根據(jù)業(yè)務(wù)需求定義的基礎(chǔ)表和業(yè)務(wù)表, 是傳統(tǒng)的數(shù)據(jù)庫表; AD表保存了業(yè)務(wù)實(shí)體表的基本屬性, 建立了表與顯示容器、 表字段及數(shù)據(jù)類型與顯示組件的對應(yīng)關(guān)系, 它位于元數(shù)據(jù)層, 因而知道數(shù)據(jù)如何訪問、 如何關(guān)聯(lián).
本文基于開源項(xiàng)目Adempiere ERP的應(yīng)用字典設(shè)計[2], 提出一種應(yīng)用字典三層架構(gòu)模型, 并闡述了應(yīng)用字典的層次結(jié)構(gòu)和數(shù)據(jù)的邏輯關(guān)系, 是對應(yīng)用字典技術(shù)的擴(kuò)充和完善.
應(yīng)用程序的發(fā)展經(jīng)歷了單層、 雙層架構(gòu)模式和MVC(模型-視圖-控制邏輯)三層架構(gòu)模式. 現(xiàn)代軟件設(shè)計一般采用可定制化的方法, 滿足客戶多樣個性化和不斷發(fā)展變化的需求. 實(shí)現(xiàn)可定制化的有效方法是將顯示屬性、 數(shù)據(jù)驗(yàn)證規(guī)則從視圖代碼中分離; 將業(yè)務(wù)流程的控制屬性從控制邏輯代碼中分離, 與數(shù)據(jù)庫中業(yè)務(wù)實(shí)體表的屬性信息一并存入中央數(shù)據(jù)庫中, 形成統(tǒng)一的屬性總庫, 構(gòu)建應(yīng)用字典. 因而應(yīng)用字典的數(shù)據(jù)模型也具有三層結(jié)構(gòu): 核心AD層、 視圖AD層和邏輯AD層.
核心AD層是數(shù)據(jù)庫中表、 字段的基本屬性集合, 包括其數(shù)據(jù)類型、 引用及驗(yàn)證規(guī)則等. 它為上兩層的構(gòu)建提供了最基本的結(jié)構(gòu)信息和數(shù)據(jù)間的依賴關(guān)系、 驗(yàn)證及約束規(guī)則. 視圖AD層描述各字段在客戶端界面中的展現(xiàn)規(guī)則. 定制開發(fā)人員不需要編寫大量的界面代碼, 即可實(shí)現(xiàn)動態(tài)界面展示、 插入、 修改、 刪除等基本數(shù)據(jù)庫操作. 邏輯AD層是從應(yīng)用軟件中抽象出控制業(yè)務(wù)流程的各類參數(shù), 以計算機(jī)化的表示模型存儲于數(shù)據(jù)庫中. 業(yè)務(wù)流程不再由編碼實(shí)現(xiàn), 而是采用一定的規(guī)范定制, 當(dāng)業(yè)務(wù)增長引起業(yè)務(wù)流程變化時, 只需修改流程定義即可完成業(yè)務(wù)流程的再造.
應(yīng)用字典的三層結(jié)構(gòu)中, 核心AD層位于最底層, 它為視圖AD層和邏輯AD層提供基礎(chǔ)數(shù)據(jù)的支撐和一致的規(guī)則.
核心AD層數(shù)據(jù)庫的實(shí)體關(guān)系如圖1所示.
圖1 核心AD層數(shù)據(jù)庫的實(shí)體關(guān)系Fig.1 Entity relationship of AD core layer
表AD_Table和表AD_Column是應(yīng)用字典技術(shù)最核心的兩張表. 表AD_Table主要用于記錄業(yè)務(wù)表的表名信息, 其中字段Name表示數(shù)據(jù)庫表的邏輯名稱, 一般用于顯示窗體的題頭; TableName表示表的名稱. AD中既可以存儲物理表也可以存儲視圖(View)[3]. 表AD_Column用于記錄字段屬性及顯示、 控制邏輯, 其關(guān)鍵數(shù)據(jù)結(jié)構(gòu)列于表1[4].
表AD_Column中存儲的信息主要分為三類: 1) 用于顯示和報表控制的邏輯信息; 2) 字段驗(yàn)證及合法性約束信息; 3) 表在創(chuàng)建時(Create table)的重要屬性信息.
AD_Table和AD_Column兩張表的核心作用: 兩張表中保存著表、 字段的名稱信息、 主鍵信息(IsKey)、 關(guān)聯(lián)信息(IsParent)、 引用類型(AD_Reference_ID)等, 使應(yīng)用程序知道如何訪問數(shù)據(jù)及數(shù)據(jù)是如何關(guān)聯(lián)的. 并且在表AD_Column中將ColumnName(表中字段名稱)和AD_Reference_ID(引用類型)進(jìn)行了綁定, 從而建立了業(yè)務(wù)實(shí)體表字段和界面中顯示組件類型的映射關(guān)系. 這種映射關(guān)系是實(shí)現(xiàn)動態(tài)生成查詢和維護(hù)畫面、 動態(tài)生成統(tǒng)計報表、 自動生成持久化類代碼的關(guān)鍵.
表1 表AD_Column的關(guān)鍵結(jié)構(gòu)
最后, 核心AD層中定義了與數(shù)據(jù)自身相關(guān)的驗(yàn)證規(guī)則及合法性約束信息, 為視圖AD層、 邏輯AD層的數(shù)據(jù)訪問提供了一致的規(guī)則. 其中的關(guān)鍵字段設(shè)計如下.
1) AD_Reference_ID(引用類型). 該字段有兩個作用: 關(guān)聯(lián)數(shù)據(jù)庫表字段的類型和關(guān)聯(lián)界面中顯示組件的類型. 表中字段的數(shù)據(jù)類型不同, 使用的顯示組件也不同[5].
所有引用類型定義在表AD_Reference中, 字段(AD_Reference_ID)中保存著引用類型指向記錄, 即唯一鍵值(primary key). 對于大數(shù)據(jù)量參數(shù)的引用類型, AD_Ref_Table表中定義參數(shù)源表的基本屬性; 對于有相互關(guān)聯(lián)關(guān)系的引用類型, 表AD_Val_Rule中定義引用參數(shù)的關(guān)聯(lián)或控制條件[6].
2) Callout(外部程序調(diào)用). 外部程序調(diào)用就是調(diào)用存儲在數(shù)據(jù)庫中的一段輕量級程序代碼, 即可以加載一個運(yùn)行時才得知名稱的類, 獲悉其完整構(gòu)造. 在顯示組件焦點(diǎn)丟失時觸發(fā)執(zhí)行該段代碼. Callout功能的設(shè)置使界面輸入域具有智能、 動態(tài)的顯示特點(diǎn), 典型的應(yīng)用表現(xiàn)如下:
① 加載或改變動態(tài)顯示信息. 如在訂單明細(xì)中, 單價、 數(shù)量和產(chǎn)品單位等字段使用同一個Callout, 每次數(shù)量、 單價或產(chǎn)品單位發(fā)生變化后, 系統(tǒng)自動更新總價;
② 在焦點(diǎn)離開時對字段數(shù)據(jù)進(jìn)行合法性校驗(yàn);
③ 控制字段在界面中的顯示邏輯. 如在婚姻狀態(tài)字段中, 如果用戶選擇“未婚”, 則界面中就不用出現(xiàn)“配偶姓名”等的輸入項(xiàng);
④ 移動焦點(diǎn)到指定顯示組件.
3) 數(shù)據(jù)格式化及合法性約束. 表AD_Column中的一些字段控制數(shù)據(jù)的顯示格式及合法輸入范圍. FieldLength約束輸入信息的最大長度; IsMandatory約束字段必須輸入, 不可為空; ValueMin和ValueMax兩個字段約束輸入值的范圍; VFormat為輸入值格式描述, 可以限制輸入空格、 只字母、 大小寫、 只數(shù)字等.
4) IsParent(外鍵關(guān)聯(lián)). 業(yè)務(wù)實(shí)體表中兩張表具有父子關(guān)系, 從父表到子表是一對多的數(shù)量關(guān)系, 因此子表中每條記錄包含父表的主鍵標(biāo)識, 該標(biāo)識不需客戶輸入, 在客戶界面中由父窗體向子窗體自動傳遞. AD中使用字段AD_Column.IsParent定義這種關(guān)聯(lián). 系統(tǒng)自動獲取父表同名字段值存入子表[7].
視圖AD層位于核心AD層上, 是客戶界面的抽象描述. 該層主要解決軟件系統(tǒng)的功能導(dǎo)航主菜單定制產(chǎn)生, 動態(tài)生成客戶界面顯示窗體, 動態(tài)生成統(tǒng)計報表, 支持用戶編程實(shí)現(xiàn)的功能模塊配置到主菜單. 主要由表AD_Menu,AD _Form,AD_Task和AD_process支撐. 實(shí)體關(guān)系如圖2所示[8].
圖2 視圖AD層的實(shí)體關(guān)系Fig.2 Entity relationship of AD view layer
表AD_Menu主要用于保存應(yīng)用系統(tǒng)主菜單信息表, 它與AD_Window,AD_Form,AD_Task,AD_Porcess是一對一的關(guān)系, Action_ID字段保存上述4張表的主鍵標(biāo)識. 表AD_Window存儲動態(tài)生存維護(hù)窗體的屬性信息, AD_Window在客戶界面上表現(xiàn)為一個顯示容器, 其中可放置多個(或一個)功能相關(guān)的Tab面板. 表AD_Form和表AD_Task定義用戶編碼生成的窗體信息并執(zhí)行操作系統(tǒng)命令, 這兩個接口模塊可將用戶編程實(shí)現(xiàn)的功能模塊配置到系統(tǒng)中統(tǒng)一管理, 增強(qiáng)了系統(tǒng)的適應(yīng)性. 表AD_Process存儲了動態(tài)生成統(tǒng)計報表的屬性信息.
如圖2所示, 表AD_Tab,AD_Field和AD_FieldGroup構(gòu)建了動態(tài)維護(hù)界面的數(shù)據(jù)模型. 應(yīng)用程序依據(jù)該模型, 動態(tài)產(chǎn)生與用戶交互的界面. 在客戶界面中, 表AD_Tab表現(xiàn)為一個Tab面板. 一個Tab只能對應(yīng)一個數(shù)據(jù)庫中業(yè)務(wù)實(shí)體表, 因此AD_Tab和AD_Table是一對一關(guān)系, 多個功能相關(guān)的Tab放入一個窗體容器中, 一個Tab中可以包含另一個Tab, 所以表AD_Tab有遞歸關(guān)系. 具有主從關(guān)系的表在窗體中以頁簽縮進(jìn)的形式表現(xiàn)其層次關(guān)系, 在表AD_Tab中以字段TabLevel數(shù)值大小標(biāo)識. 表AD_Field的結(jié)構(gòu)依賴核心層的表AD_Column, 是業(yè)務(wù)表字段在顯示界面中顯示屬性的描述, 主要包括顯示域的位置、 顯示域的長度等信息. 多個Field放在一個Tab中, 構(gòu)成一個業(yè)務(wù)實(shí)體表的維護(hù)畫面.
表AD_Process,AD_RepoatView及實(shí)線框內(nèi)的表構(gòu)建了動態(tài)統(tǒng)計報表的數(shù)據(jù)模型(圖2). 報表數(shù)據(jù)來源于業(yè)務(wù)實(shí)體表, 格式定義在AD字典中. 數(shù)據(jù)來源跨多張業(yè)務(wù)表獲取時, 定義邏輯視圖表(View)將多張業(yè)務(wù)表聯(lián)接(Join), 視圖表描述在AD_RepoatView中. 表AD_ printFormat描述了打印報表的樣式及字段的打印格式, 其中: AD_Paper定義打印紙屬性; AD_PrintColor及AD_PrintFont 定義打印字體、 字號和顏色屬性. AD_printFormat Item定義視圖中每個打印字段的打印屬性, 它依賴于核心層表AD_Column中的字段定義.
邏輯AD層是對業(yè)務(wù)控制流程的抽象描述, 是將業(yè)務(wù)流程計算機(jī)化的表示模型. 該層數(shù)據(jù)模型的設(shè)計得益于工作流管理聯(lián)盟(WFMC)的工作流管理系統(tǒng)參考模型[9-10], 它將現(xiàn)實(shí)世界中的業(yè)務(wù)流程抽象成動作、 路由和參與者3個對象. 動作又稱為活動, 是構(gòu)成業(yè)務(wù)流程的基本單元, 主要反映完成業(yè)務(wù)流程所需計算機(jī)執(zhí)行的操作. 動作可以由人負(fù)責(zé)執(zhí)行, 也可以由系統(tǒng)自動判斷執(zhí)行. 路由決定了動作的執(zhí)行順序, 它的基本結(jié)構(gòu)有: 順序執(zhí)行、 并行執(zhí)行、 選擇執(zhí)行和循環(huán)執(zhí)行. 通過基本結(jié)構(gòu)的組合搭配, 可延伸出更多的路由結(jié)構(gòu). 參與者是具備一定工作能力的人、 機(jī)器或應(yīng)用程序, 它能執(zhí)行特定任務(wù), 參與動作的執(zhí)行, 完成流程執(zhí)行工作[11]. 業(yè)務(wù)流程數(shù)據(jù)模型如圖3所示.
圖3 邏輯AD層的實(shí)體關(guān)系Fig.3 Entity relationship of AD controler layer
表AD_WorkFlow存儲流程的唯一標(biāo)識, 用主鍵AD_WorkFlow_ID表示一個流程的定義. 工作流根據(jù)其應(yīng)用場景劃分成如下3種類型.
1) 標(biāo)準(zhǔn)工作流: 是提供給用戶一步步執(zhí)行任務(wù)的步驟指南. 該系列的任務(wù)包括配置在表AD_WINDOW中的窗體, 表AD_FORM中的表單, 表AD_PROCESS中的報表打印等功能模塊. 用戶可以通過系統(tǒng)主菜單訪問預(yù)定義的標(biāo)準(zhǔn)工作流.
2) 單據(jù)流轉(zhuǎn)工作流: 系統(tǒng)中的所有單據(jù)(采購申請單、 報銷單等)都可以自動使用工作流, 它基于表信息配置. 本文在AD_workFlow中設(shè)計AD_Table_ID字段, 就是要實(shí)現(xiàn)如果任何涉及到AD_Table_ID指向表的活動, 則將激活這個單據(jù)流程工作.
3) 單據(jù)值工作流: 當(dāng)用戶保存單據(jù)數(shù)據(jù)或系統(tǒng)自動更新單據(jù)中某個字段時, 系統(tǒng)有一個可監(jiān)控字段條件值的機(jī)制, 當(dāng)某條件滿足(為“真”)時, 即觸發(fā)單據(jù)值工作流執(zhí)行. 為了實(shí)現(xiàn)單據(jù)值工作流, 在表AD_Workflow中設(shè)計DocValueLogic字段定義觸發(fā)條件.
業(yè)務(wù)流程的動作被映射到AD_WF_Node節(jié)點(diǎn)表中, 一個業(yè)務(wù)流程由多個動作構(gòu)成, 因此表AD_WorkFlow到表AD_WF_Node是一對多的關(guān)系. 在一個流程節(jié)點(diǎn)描述中必須有一個開始節(jié)點(diǎn), AD_WorkFlow.AD_WF_Node_ID就指向該開始節(jié)點(diǎn). 此外, 它還包括如下類型的節(jié)點(diǎn).
1) 等待節(jié)點(diǎn)(wait): 該節(jié)點(diǎn)指定在系統(tǒng)執(zhí)行下一個節(jié)點(diǎn)前等待時間;
2) 用戶選擇節(jié)點(diǎn)(user choice): 該節(jié)點(diǎn)請求用戶交互;
3) 用戶操作節(jié)點(diǎn)(user Action): 該節(jié)點(diǎn)也需要用戶, 用戶可以打開AD_Window_ID指向的窗體, AD_Foem_ID指向的表單, AD_Task_ID指向的任務(wù)和AD_Process_ID指向的報表;
4) 自動過程節(jié)點(diǎn)(Automatic processes): 該節(jié)點(diǎn)自動執(zhí)行, 不需要用戶交互.
路由被抽象成節(jié)點(diǎn)間的變遷條件, 它被存儲在表AD_WF_NodeNext中. 字段AD_WF_Node_ID和AD_WF_Next_ID標(biāo)識一個節(jié)點(diǎn)到另一個節(jié)點(diǎn)的變遷, 字段Condition描述了變遷的條件. 基本的路由結(jié)構(gòu)實(shí)現(xiàn)方法如下.
1) 順序執(zhí)行: 當(dāng)一個節(jié)點(diǎn)有且只有一個下個節(jié)點(diǎn)時, 流程按預(yù)定義步驟依次執(zhí)行;
2) 選擇執(zhí)行: 當(dāng)一個節(jié)點(diǎn)有多個下個節(jié)點(diǎn)時, Condition字段決定了流程的路由選擇;
3) 并發(fā)執(zhí)行: 當(dāng)一個節(jié)點(diǎn)有多個條件相同的下個節(jié)點(diǎn)時, 這些節(jié)點(diǎn)會并發(fā)執(zhí)行;
4) 循環(huán)執(zhí)行: 當(dāng)滿足某條件時, AD_WF_Next_ID指向前面循環(huán)開始節(jié)點(diǎn). 當(dāng)條件不滿足時, 指向退出循環(huán)節(jié)點(diǎn).
表AD_WF_Node的字段AD_WF_Responsible_ID指向動作的參與者. 參與者可以是某個用戶, 也可以是某類人(角色或組織). 參與者與節(jié)點(diǎn)綁定, 可以為流程中每個動作指定參與人.
邏輯AD層實(shí)現(xiàn)了業(yè)務(wù)流程的描述與程序代碼分離, 在傳統(tǒng)的編程模式下, 代碼邏輯結(jié)構(gòu)反映了業(yè)務(wù)流程的執(zhí)行步驟, 程序設(shè)計人員不僅需要具備編程技能, 還要熟悉業(yè)務(wù)流程. 這種將業(yè)務(wù)流程從代碼中獨(dú)立出來, 通過配置完成業(yè)務(wù)流程的描述, 降低了開發(fā)難度, 加速了開發(fā)進(jìn)程.
綜上所述, 應(yīng)用字典是實(shí)現(xiàn)信息管理軟件可定制化的關(guān)鍵技術(shù)[12]. 將顯示屬性、 業(yè)務(wù)控制邏輯屬性及數(shù)據(jù)庫的基本屬性從程序代碼中分離出來構(gòu)成應(yīng)用字典, 從而增強(qiáng)了程序代碼的通用性和動態(tài)性, 是縮短開發(fā)周期、 降低開發(fā)成本、 增強(qiáng)系統(tǒng)運(yùn)行穩(wěn)定性的有效方法.
[1] SU Hao. Application Dictionary Technology Research [J]. Natural Science Journal of Southwest University for Nationalities, 2008, 34(4): 868-870. (蘇浩. 應(yīng)用字典技術(shù)的研究 [J]. 西南民族大學(xué)學(xué)報: 自然科學(xué)版, 2008, 34(4): 868-870.)
[2] Adempiere Community. Adempiere ERP Open-Source Software (Version 370LTS) [EP/OL]. 2011-09-01. http://www.adempiere.org/site.
[3] Adempiere Community. Adempiere Development Community Wiki [EB/OL]. 2012-01-10. http://www.adempiere.com/Adempiere_Development_Community_Wiki.
[4] Adempiere Team. Table_of_Contents [EB/OL]. 2012-07-23. http://www.adempiere.com/index.php/Table_of_Contents.
[5] Openbravo Community. Openbravo ERP Developers Guide [EB/OL]. 2011-08-11. http://wiki.openbravo.com/wiki/ERP_2.50: Developers_Guide.
[6] Adempiere Team. Application Dictionary [EB/OL]. 2011-12-21. http://www.adempiere.com/Table_and_Column#Table_and_Column.
[7] Adempiere Community. Adempiere ERP Documentation [EB/OL]. 2012-02-16. http://www.adempiere.com/Adempiere_ERP.
[8] Bayn Cahya Pamungkas. ADempiere 3.4 ERP Solutions [M]. Birmingham: Packt Publishing, 2009.
[9] Adempiere Team. Application Dictionary Layers [EB/OL]. 2011-01-01. http://www.adempiere.com/Application_Dictionary_Layers.
[10] Adempiere Team. Workflow [EB/OL]. 2011-12-22. http://www.adempiere.com/Workflow.
[11] 侯志松. 工作流管理系統(tǒng)開發(fā)實(shí)錄——基于JBoss jBPM實(shí)現(xiàn) [M]. 北京: 中國鐵道出版社, 2010: 69-107.
[12] Adempiere Team. ADempiere Rapid Development [EB/OL]. 2011-02-27. http://www.adempiere.com/ADempiere_Rapid_Development.