戎小群
摘要:在軟件開發(fā)過程中,隨著軟件開發(fā)的進(jìn)展,代碼的冗余已經(jīng)成為不可忽視的現(xiàn)象,這嚴(yán)重地影響軟件開發(fā)的進(jìn)度,同時(shí)也會(huì)造成系統(tǒng)維護(hù)的困難,因此代碼是否精簡(jiǎn)直接影響應(yīng)用系統(tǒng)的可維護(hù)性。該文通過具體的案例來說明,如何在恰當(dāng)?shù)貞?yīng)用面向?qū)ο笤O(shè)計(jì)模式的基礎(chǔ)上,解決代碼冗余的方法,以提高應(yīng)用系統(tǒng)的可維護(hù)性。
關(guān)鍵詞:面向?qū)ο笤O(shè)計(jì)原則;模板方法模式;DAO模式;代碼冗余
中圖分類號(hào):TP311? ? ? ?文獻(xiàn)標(biāo)識(shí)碼:A? ? ? 文章編號(hào):1009-3044(2018)36-0227-03
1 背景
軟件開發(fā)過程中,常常會(huì)伴隨著代碼冗余,它降低了軟件應(yīng)用系統(tǒng)的可維護(hù)性,從而影響軟件應(yīng)用系統(tǒng)開發(fā)效率。按照目前軟件迭代開發(fā)的理論,軟件開發(fā)需要首先完成初始可運(yùn)行的版本,然后逐漸迭代,最終達(dá)到面向?qū)ο蟮脑O(shè)計(jì)目標(biāo),其中也包含了減少代碼冗余。因此,在迭代過程中,需要仔細(xì)分析可能出現(xiàn)代碼冗余的模塊,通過設(shè)計(jì)技術(shù)手段,消除代碼冗余,最終提高軟件開發(fā)效率,確保軟件系統(tǒng)的可維護(hù)性。
該文就是討論如何應(yīng)用合適的面向?qū)ο笤O(shè)計(jì)模式,在實(shí)現(xiàn)數(shù)據(jù)批量處理過程中,消除代碼冗余的方法。
2 面向?qū)ο蟮脑O(shè)計(jì)
2.1 面向?qū)ο笤O(shè)計(jì)目標(biāo)
可擴(kuò)展性(Extensibility):可以將新功能添加到系統(tǒng)中。
靈活性(Flexibility):在添加新功能代碼的過程中,盡可能地減少修改量。
可插入性(Pluggability):能將一個(gè)組件替換具有同樣接口的另一個(gè)組件。
2.2 面向?qū)ο蟮脑O(shè)計(jì)原則
在常用的面向?qū)ο笤O(shè)計(jì)原則中,開-閉原則(The Open-Close Principle,OCP)是面向?qū)ο蟮目蓮?fù)用設(shè)計(jì)的基石,此外還有單一職責(zé)原則(The Single Responsiblity Principle,SRP)、Liskov替換原則(The Liskov Substitution Principle,LSP)、依賴倒置原則(The Dependency Inversion Pricinple,DIP)和接口隔離原則等。這些設(shè)計(jì)原則是實(shí)現(xiàn)“開-閉原則”的手段和工具。
2.3 面向?qū)ο笤O(shè)計(jì)的具體思路
1) 在客戶端盡量采用面向抽象或接口編程;
2) 高內(nèi)聚,低耦合;
3) 采用恰當(dāng)?shù)拿嫦驅(qū)ο笤O(shè)計(jì)模式,以提高軟件開發(fā)的效率,達(dá)到減少代碼冗余的目的。
2.4 面向?qū)ο蟮脑O(shè)計(jì)模式
設(shè)計(jì)模式(Design pattern)是一套能被反復(fù)使用的代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)。它使代碼編寫真正實(shí)現(xiàn)了工程化,是軟件工程的基石脈絡(luò)。
1) 數(shù)據(jù)訪問對(duì)象(DAO)模式:主要用于軟件架構(gòu)的數(shù)據(jù)層,其主要功能為完成數(shù)據(jù)的編輯(添加、刪除和修改)與查詢。
DAO模式通常需要VO(值對(duì)象),通常一個(gè)DAO對(duì)應(yīng)一個(gè)VO對(duì)象。
2) 模板方法模式:在父類中定義一個(gè)通用的操作,將其中一些具體功能延遲到子類中,從而在不改變?cè)僮鞫x的條件下實(shí)現(xiàn)功能的擴(kuò)展。
模版方法模式通常由一個(gè)抽象類和若干個(gè)具體子類組成,抽象類中的方法分為三種:
2.5 數(shù)據(jù)批量處理時(shí)的代碼冗余現(xiàn)象
信息管理應(yīng)用系統(tǒng)在信息處理時(shí),均會(huì)頻繁地訪問數(shù)據(jù)庫,訪問數(shù)據(jù)庫的目的主要由如下幾種形式:
1) 往數(shù)據(jù)庫添加數(shù)據(jù);
2) 修改數(shù)據(jù)庫中的數(shù)據(jù);
3) 刪除數(shù)據(jù)庫中的數(shù)據(jù);
4) 查詢數(shù)據(jù)庫中的數(shù)據(jù)。
在應(yīng)用軟件系統(tǒng)中,常用數(shù)據(jù)層來完成與數(shù)據(jù)庫的交互,常常采用DAO(數(shù)據(jù)訪問)模式。由于數(shù)據(jù)庫的連接是一個(gè)“貴重”資源,因此,為了提高效率,常常要求一次連接能夠完成批量數(shù)據(jù)的處理。那么如何才能高效地完成數(shù)據(jù)批量的處理(即,增刪改查)?
2.6 模板方法模式在批量數(shù)據(jù)處理中的應(yīng)用
2.6.1 案例
假設(shè)數(shù)據(jù)庫testdb中包含兩個(gè)roles和users兩個(gè)表對(duì)象。這兩個(gè)表對(duì)象的結(jié)構(gòu)如下:
在對(duì)數(shù)據(jù)庫中的表進(jìn)行訪問時(shí),通常建立表與VO(值對(duì)象)類一一對(duì)應(yīng)關(guān)系,如,以上兩表各自建立一個(gè)JaveBean(Role和User)類,類中的屬性分別對(duì)應(yīng)表中的字段。同時(shí)分別創(chuàng)建兩個(gè)訪問兩個(gè)表數(shù)據(jù)的DAO(RoleDAO和UserDAO)類。一旦數(shù)據(jù)庫表的數(shù)量增加,相應(yīng)的DAO也需要增加,代碼的冗余將會(huì)產(chǎn)生;另外,即使對(duì)數(shù)據(jù)庫中的一個(gè)表進(jìn)行批量數(shù)據(jù)處理時(shí)(增刪改查),也會(huì)出現(xiàn)代碼的冗余。
2.6.2 設(shè)計(jì)思路
首先,解決批量數(shù)據(jù)處理時(shí)的編輯(即,增刪改)操作所引起的代碼冗余。
在對(duì)數(shù)據(jù)庫表進(jìn)行編輯(增刪改)操作時(shí),所有與表對(duì)應(yīng)的VO(值對(duì)象)類都附加一個(gè)操作碼,以代表是何種編輯(增加、刪除、修改)。由此,從VO類中抽象出一個(gè)所有VO類的共同父類AbstractData,此類為抽象類。如圖2所示。
<E:\電腦第36期\電腦第36期打包文件\8.7xs201836\Image\image55.png>
圖2? ? VO類圖
通過應(yīng)用模板方法模式,創(chuàng)建DAO類的父類AbstractDAO,該類為抽象類。如圖3所示。
AbstractDAO中的方法說明:
1) 模板方法:
protected final int addRecords(Connection conn, ArrayList<AbstractData>datas)
protected final int deleteRecords(Connection conn, ArrayList
protected final int updateRecords(Connection conn, ArrayList<AbstractData>datas)
2) 抽象方法:
如下的三個(gè)方法分別完成返回添加、刪除和修改的SQL語句的功能。
protected abstract String getAddSQL()
protected abstract String getDeleteSQL()
protected abstract String getUpdateSQL()
如下的三個(gè)方法分別完成對(duì)象轉(zhuǎn)化為記錄的功能。
protected abstract void handleAdd(PreparedStatementpstm, ArrayList<AbstractData>)
protected abstract void handleDelete(PreparedStatementpstm, ArrayList<AbstractData>)
protected abstract void handleUpdate(PreparedStatementpstm, ArrayList<AbstractData>)
以上六個(gè)抽象方法,均由DAO子類實(shí)現(xiàn)。
模板方法的代碼示例如下:
protected final int addRecords(Connection conn, ArrayList<AbstractData>datas){
int count = 0;
String sql = getAddSQL();
try{
PreparedStatementpstm = conn.prepareStatement(sql);
handleAdd(pstm, datas);
int[] amt = pstm.executeBatch();
for(int i = 0; i < amt.length; i++){
count += amt[i];
}}catch(SQLException e){
}finally{
if(pstm != null){
pstm.close();
}}return count;
}public String editRecords(ArrayList<AbstractData>datas){
ArrayList<AbstractData>addList = new ArrayList<AbstractData>();
…
Connection conn = ConnectionFactroy.getConnection();
int add = addRecords(conn, addList);
…}
DAO類的繼承關(guān)系如圖4所示。
DAO類與VO類之間的關(guān)系如圖5所示。
3 結(jié)束語
在進(jìn)行軟件開發(fā)的過程中,需要靈活恰當(dāng)?shù)貞?yīng)用設(shè)計(jì)模式,并將幾種設(shè)計(jì)模式進(jìn)行組合,在應(yīng)用設(shè)計(jì)模式時(shí),需要掌握設(shè)計(jì)模式的應(yīng)用場(chǎng)合以及能解決什么開發(fā)問題。在應(yīng)用設(shè)計(jì)模式時(shí),要注意以下幾個(gè)方面的問題:
1) 不能在需求不明確時(shí),確定設(shè)計(jì)模式;
2) 不能為了設(shè)計(jì)模式而使用設(shè)計(jì)模式;
3) 不能“生搬硬套”設(shè)計(jì)模式;
4) 在迭代開發(fā)的過程中,完善與明確設(shè)計(jì)模式。
參考文獻(xiàn):
[1] 23種設(shè)計(jì)模式(6):模版方法模式[EB/OL].http://www.importnew.com/15546.html.
[2] Alan Shalloway, James R Trott.設(shè)計(jì)模式解析[M]. 徐言聲, 譯.2版. 北京:人民郵電出版社, 2007(10).
[3] 巴拉赫,蘭寶. UML面向?qū)ο蠼Ec設(shè)計(jì)[M].車皓陽,楊眉, 譯. 2版.北京:人民郵電出版社, 2006(1).
[通聯(lián)編輯:謝媛媛]