序言
本文分享一個通過數據庫(ORACLE)的存儲過程,遵循“對修改封閉,對增加開放”的開閉原則,實現的可擴展性極強的靈活接口方案。
背景
本人從事離散型MES系統的開發工作,近期負責了一個PCBA(電子、手機)行業的MES系統二開工作。PCBA行業使用ATE工具(自動測試工具)進行寫號、查號、置標志位等工作,寫號查號等相關數據需要與MES系統進行數據交互,同時MES系統也需要管控ATE工具的作業流程。如查號必須在寫號后,沒有寫號的工具不能進行查號等流程管控。由於ATE工具的測試不須人員參與,所以MES系統需要開發相關接口給ATE工具端調用,進行數據交互和流程管控等工作。
MES系統前期已有途程檢查,分配IMEI、MAC、BT數據,過站等相關基礎接口可供ATE工具調用,基本能滿足要求。但在面對某些客戶定制化的需求時(如上傳軟件版本、記錄測試內容),就必須在原有接口的基礎上增加或修改程序,然后把C#編寫的dll封裝成COM組件(因為ATE工具使用C++編寫的),更新文檔,再通知ATE工具編寫人員重新連入新版本進行編寫和調試,最后再更新現有工具的所有版本。別看流程描述起來比較簡單,但實際操作起來涉及到溝通、部門協作等問題,非常繁瑣累人。
基於上述原因,筆者思考是否有一個方案能夠靈活面對客戶的定制化需求,又不需涉及到太多變更,特別是重新編譯、重新連入和更新等操作。有志者事竟成,經過一番研究與思考后,筆者決定采用“存儲過程”來進行實現。
整體方案
方案詳述
為了更好的講述該方案,下面將以代碼(或偽代碼)的方式進行講述。
接口方法調用存儲過程
public bool SetATEData(string iCmdType, string iText, out string oText, out string oErrMessage) { return ExecProc.ProcInputPara(iCmdType, iText, out oText, out oErrMessage); }
對該方法的詳細介紹如下:
Bool SetATEData(String iCmdType, String iText, String oText, String oErrMessage)
參數說明
iCmdType----傳入的接口代碼,如1001;可自定義
iText-----------傳入此接口參數列表,采用鍵值對的方式傳入,以“|”分隔,例如:
“Field1=Value1|Field2=Value2|Field3=Value3|... … ”(也可定義其他分隔符,如有需要,請考慮轉義字符)
oText----------如接口需要返回參數的列表,采用鍵值對的方式輸出,以“|”分隔,例如:
“Key1=Value1| Key2=Value2| Key3=Value3|... … “,可為空
oErrMessage----當方法返回false時,傳出具體的出錯信息
注:
ExecProc.ProcInputPara(iCmdType, iText, out oText, out oErrMessage)是筆者寫的一個靜態方法,用於調用存儲過程。實際應用中需要自行編寫。為了做好記錄,筆者也會上傳該靜態類,僅供參考。
存儲過程統一入口
根據傳入的iCmdType查詢對應的存儲過程名稱,若存在則動態執行該存儲過程。
儲存存儲過程的表格結構如下所示:
存儲過程的代碼(ORACLE 11g版本)如下所示:
CREATE OR REPLACE PROCEDURE PROCDLLBASE (ICMDTYPE IN VARCHAR2,ITEXT IN VARCHAR2,OTEXT OUT VARCHAR2,OERRMSG OUT VARCHAR2,ORESULT OUT INTEGER) AS v_Sql varchar2(4000); v_ProcName TBLPROCGROUP.PROCNAME%TYPE; i_ProcCount integer; BEGIN SELECT COUNT(1) INTO i_ProcCount from TBLPROCGROUP where PROCID=ICMDTYPE; IF i_ProcCount=0 THEN OERRMSG:='CMDTYPE2PROC_NOT_FOUND'; ORESULT:=0; RETURN; END IF; SELECT PROCNAME INTO v_ProcName from TBLPROCGROUP where PROCID=ICMDTYPE; v_Sql:='begin '|| v_ProcName || '(:itext,:otext,:oerrmsg,:oresult);end;'; EXECUTE IMMEDIATE v_Sql using in ITEXT,out OTEXT,out OERRMSG,out ORESULT; EXCEPTION WHEN OTHERS THEN ROLLBACK; OERRMSG:='CMDTYPE2PROC_UNKNOWN_ERROR'; ORESULT:=0; RETURN; END PROCDLLBASE;
子存儲過程
根據業務需求編寫對應的存儲過程,並將iCmdType與存儲過程名稱關聯后儲存至TBLPROCGROUP表格中。
子存儲過程中涉及到輸入參數的解析,輸入參數的非空性校驗及重復性校驗,這些都是保證系統穩健性的需要。
總結
通過上述方案,當客戶再有其他需求時,只需根據業務邏輯創建存儲過程並分配iCmdType與之關聯即可實現接口的擴展。
ATE工具開發人員也只需要按照文檔的格式傳參並解析輸出參數即可,免卻編譯程序,封裝COM組件及更新的繁瑣流程。