国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

設(shè)計模式在數(shù)據(jù)存儲設(shè)計中的應(yīng)用

2013-04-25 05:52:08張欲蓉
艦船電子對抗 2013年1期
關(guān)鍵詞:子類職責(zé)代碼

張欲蓉,嚴(yán) 華

(中國電子科技集團公司51所,上海 201802)

0 引 言

數(shù)據(jù)存儲是各種計算機應(yīng)用系統(tǒng)的一個重要功能。幾乎所有的計算機應(yīng)用系統(tǒng)都需要將各種數(shù)據(jù)信息存儲為不同格式的文件。在存儲過程中,數(shù)據(jù)導(dǎo)出與數(shù)據(jù)保存的代碼很容易高度耦合,很難分別對數(shù)據(jù)導(dǎo)出與數(shù)據(jù)保存部分單獨進行修改、擴充與重用。本文所述的數(shù)據(jù)存儲設(shè)計,運用bridge和decorator模式,將數(shù)據(jù)導(dǎo)出與數(shù)據(jù)保存解耦,使設(shè)計易維護、易擴展、易復(fù)用。

1 問題分析

在某個典型的電子對抗領(lǐng)域的應(yīng)用中,有上級指控命令、信號分選結(jié)果、系統(tǒng)工作日志等數(shù)據(jù)需要存儲,這些數(shù)據(jù)可能需要被存儲為多種格式的文件,如*.xls、*.txt、*.html或*.mdb等。實現(xiàn)數(shù)據(jù)存儲功能的最常見的2種設(shè)計如下:

設(shè)計1:設(shè)計一個模塊,讓其提供多個接口來滿足需要,這種設(shè)計缺點很明顯,降低了代碼的內(nèi)聚性,使之趨于不良耦合,可重用性和可靠性大打折扣。

圖1 設(shè)計2的設(shè)計類圖

根據(jù)這種設(shè)計,假設(shè)系統(tǒng)數(shù)據(jù)的種類為M,文件格式的種類為N,則一共要設(shè)計M×N個類才能滿足要求。這種設(shè)計存在如下問題:(1)每增加一種待導(dǎo)出的數(shù)據(jù)或增加一種文件導(dǎo)出格式,需要增加多個類;(2)如果對待導(dǎo)出數(shù)據(jù)或文件的保存格式進行修改將影響與之相關(guān)的多個類;(3)隨著M或N值的增加,最終設(shè)計類的個數(shù)會增長為不可控制的龐然大物。

本文所要解決的問題就是提出一種設(shè)計,這種設(shè)計能減少類的數(shù)量,降低類間的耦合度,保持對象的內(nèi)聚性,易理解,易管理,減少變化帶來的影響,提高重用性[1]。

2 系統(tǒng)設(shè)計

軟件設(shè)計真正要做的許多內(nèi)容,就是發(fā)現(xiàn)職責(zé)并把職責(zé)相互分離[2]。將待導(dǎo)出的數(shù)據(jù)視為數(shù)據(jù)源,將數(shù)據(jù)存儲的過程分解為導(dǎo)出和保存2步:導(dǎo)出的職責(zé)是按需求過濾、提取、組織數(shù)據(jù),保存的職責(zé)是將組織好的數(shù)據(jù)保存為不同格式文件。經(jīng)分解后2個職責(zé)都比較單一,更能適應(yīng)變化的發(fā)生。數(shù)據(jù)存儲的過程如圖2所示。

圖2 數(shù)據(jù)存儲示意圖

2.1 類的設(shè)計

設(shè)計類圖見圖3。

圖3 設(shè)計類圖

這里設(shè)計了2個抽象基類:CExport和CSave。CExport提供數(shù)據(jù)導(dǎo)出的接口,CSave提供數(shù)據(jù)保存的接口。CDB代表數(shù)據(jù)源的抽象,設(shè)計時應(yīng)讓其提供接口,使其他對象能夠獲取數(shù)據(jù)源的數(shù)據(jù)。

CExport派生出CExport Cmd、CExportSignal和CExport Log等子類,CExportCmd子類負(fù)責(zé)導(dǎo)出上級指控命令,CExportSignal負(fù)責(zé)導(dǎo)出信號分選結(jié)果,CExport Log負(fù)責(zé)導(dǎo)出系統(tǒng)工作日志。

CSave派生出 CSaveXls、CSave Txt、CSave Html和CSave Mdb等子類,這些子類分別負(fù)責(zé)將導(dǎo)出的數(shù)據(jù)保存為xls、txt、html和mdb等格式。

有些數(shù)據(jù)文件可能需要裝飾,例如:數(shù)據(jù)文件需要增加標(biāo)題或結(jié)尾,于是設(shè)計1個抽象類CDecorat-or Export,它是CExport的子類,用于提供統(tǒng)一的裝飾接口。從CDecorator Export派生出2個子類:CDecorator Export Topic和CDecorator Export Tail。CDecorator Export Topic用于增加標(biāo)題,CDecorator Export Tail用于增加結(jié)尾。如果需要實現(xiàn)其他裝飾功能,從CDecorator Export類派生出相應(yīng)裝飾作用的類即可。

2.2 實現(xiàn)數(shù)據(jù)導(dǎo)出和數(shù)據(jù)保存的分離

按照圖1的設(shè)計,每增加一種待導(dǎo)出數(shù)據(jù)或文件導(dǎo)出格式,就需要增加多個類,最終將導(dǎo)致類的數(shù)量龐大。且一旦有變化發(fā)生,將引起多個類一起變化。究其原因,就是設(shè)計類職責(zé)過多,耦合過于緊密。緊密耦合導(dǎo)致脆弱的設(shè)計,當(dāng)變化發(fā)生時,設(shè)計不能適應(yīng)這種變化。事實上,完全可以找出哪些是數(shù)據(jù)導(dǎo)出,哪些是數(shù)據(jù)保存,然后進行職責(zé)分離,使設(shè)計符合單一職責(zé)原則[2]。

e.g. A: The dinner is ready. Tim has not made it.Can anybody give him a call?

軟件設(shè)計的一個重要原則是依賴倒置原則:高層模塊不應(yīng)該依賴低層模塊,2個都應(yīng)該依賴抽象;抽象不應(yīng)該依賴細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴抽象。針對接口編程,不要對實現(xiàn)編程。相對于實現(xiàn)細(xì)節(jié)的多變性,抽象的接口要穩(wěn)定得多。依據(jù)這個原則,設(shè)計抽象類CSave和CExport,CExport提供數(shù)據(jù)導(dǎo)出的接口;CSave提供數(shù)據(jù)保存的接口。讓CExport基類維持一個指向CSave類的指針。這樣數(shù)據(jù)導(dǎo)出CExport的各個子類對數(shù)據(jù)保存的依賴關(guān)系都終止于抽象類或接口。正是由于這個抽象的依賴關(guān)系,以及子類型對父類型的可替換,實現(xiàn)了數(shù)據(jù)導(dǎo)出和數(shù)據(jù)保存的分離。設(shè)計類圖見圖4,這種設(shè)計是bridge模式的一個應(yīng)用。

圖4 應(yīng)用bridge模式實現(xiàn)數(shù)據(jù)導(dǎo)出與數(shù)據(jù)保存的分離

CExport的子類CExportSignal、CExportCmd等和CSave的子類CSaveXls、CSave Html等之間沒有固定的綁定關(guān)系,可以在程序運行過程中根據(jù)需要選擇或切換。

下面以將信號分選結(jié)果導(dǎo)出保存為Txt和Html為例進行說明:

//對數(shù)據(jù)保存的依賴終止于抽象類CSave,可傳入指向CSave的子類的指針,將數(shù)據(jù)保存為不同格式文件。

實現(xiàn)數(shù)據(jù)導(dǎo)出與數(shù)據(jù)保存功能的客戶代碼如下:

//傳入指向CSave Txt類的指針,實現(xiàn)子類對父類的替換,將信號分選結(jié)果導(dǎo)出保存為txt文件。

m_p Export->Export(m_pSave Txt);

//傳入指向CSave Html類的指針,實現(xiàn)子類對父類的替換,將信號分選結(jié)果導(dǎo)出保存為html文件,不需要對CExportSignal作修改。

m_pExport->Export(m_pSave Html);

采用bridge模式的核心意圖,就是將數(shù)據(jù)保存獨立出來,減少與數(shù)據(jù)導(dǎo)出的耦合,讓它與數(shù)據(jù)導(dǎo)出各自獨立地變化,并且該變化對其他部分不會產(chǎn)生影響。

CExport的各個子類只負(fù)責(zé)按需求過濾、提取、組織數(shù)據(jù),將保存功能分配給了CSave的各個子類,但是它們能夠共同協(xié)作并提供某種良好界定的行為[3],因此它們具有高內(nèi)聚的性質(zhì)。每增加一種待導(dǎo)出數(shù)據(jù),只需要設(shè)計一個從CExport派生的子類即可,其他所有的類均不需要任何改變。同樣,每增加一種文件導(dǎo)出格式,只需要增加一個從CSave派生出的子類即可,其他所有類也不需要改變。職責(zé)的合理分配與依賴倒置原則的應(yīng)用,降低了CExport的子類和CSave的子類之間的耦合性,保持了對象的內(nèi)聚性。

CSave Txt、CSave Html、CSaveXls及 CSaveDoc等承擔(dān)保存文件職責(zé)的類經(jīng)過測試成熟后,便可被其他項目所復(fù)用。

2.3 數(shù)據(jù)導(dǎo)出功能的動態(tài)增加

導(dǎo)出日志時,有時需要加上導(dǎo)出日期、日志名稱等信息,或是添加在標(biāo)題處,或是添加在結(jié)尾處,有時也可能并不需要增加任何裝飾。即裝飾功能是動態(tài)增加的。如何實現(xiàn)這個動態(tài)裝飾功能呢?常見的方法是在數(shù)據(jù)導(dǎo)出類中增加接口。但是這樣就必須修改各個數(shù)據(jù)導(dǎo)出類的接口,增加新的邏輯,導(dǎo)致原有類的復(fù)雜度增加,客戶代碼也需要適應(yīng)這個新的邏輯和接口,一起作修改。當(dāng)每次增加新的裝飾功能時,修改又會再次發(fā)生在同樣的地方。在設(shè)計中應(yīng)用了decorator模式來隔離這些變化,使變化產(chǎn)生的影響降到最低。

軟件設(shè)計應(yīng)遵循的另一個原則是:開放-封閉原則,就是說軟件實體(類、模塊、函數(shù)等等)應(yīng)該可以擴展,但是不可修改[2]。即對于擴展是開放的,對于更改是封閉的。但是無論模塊設(shè)計得多么“封閉”,都會存在一些無法對之封閉的變化。既然不可能完全封閉,就創(chuàng)建抽象來隔離變化,即找出變化并封裝變化[4]。這里的變化就是動態(tài)增加的裝飾功能。設(shè)計的出發(fā)點就是讓CExport類及其子類無需知道裝飾功能的存在,即不對CExport類及其子類作任何修改,保證它們封閉性的同時,提供擴展的開放性。設(shè)計類圖見圖5,這種設(shè)計是decorator模式的一個應(yīng)用。

圖5 應(yīng)用decorator模式實現(xiàn)數(shù)據(jù)導(dǎo)出的動態(tài)增加

設(shè)計CDecorator Export類,它是用于裝飾的抽象基類,它還是CExport的子類,與被裝飾的CExport及其子類具有相同的接口。它同時維持一個指向CExport對象的指針,并改寫了從CExport繼承來的Export接口,改寫的示例代碼如下。這為在不改變CExport對象的情況下給CExport對象增加職責(zé)提供了基礎(chǔ)。

將CExport對象看作一個核,CDecorator Export對象看作它的外殼,通過套上外殼可以改變核的行為。子類CDecorator Export Topic和CDecorator Export Tail從CDecorator Export派生,將它們實例化后的對象就是核的外殼。它們提供用于裝飾的接口,給CExport對象添加新的職責(zé),一個負(fù)責(zé)增加標(biāo)題,一個負(fù)責(zé)增加結(jié)尾。它們均改寫了從CDecorator Export繼承過來的Export接口,實現(xiàn)裝飾功能。示例代碼如下:

如果需要實現(xiàn)其他裝飾功能,只需增加一個從CDecorator Export派生出來的裝飾類即可,原有的實現(xiàn)數(shù)據(jù)導(dǎo)出與數(shù)據(jù)保存功能的類不需要作任何改動。對于客戶代碼來說,通過與2.1中示例代碼的比較可知,只有實例化CExport類為對象這一個地方有改動,由于裝飾類是CExport的子類,它們具有相同接口,客戶代碼的其余地方均不需要改動。

3 其他

為了增加靈活性和封裝變化,本文在設(shè)計中選擇了細(xì)粒度的類,每個類都有比較明晰、單一的職責(zé)。使用這些細(xì)粒度類提供了更為靈活的策略,也提供了更多的可復(fù)用性。

在應(yīng)用中有一點要特別注意,由于裝飾對象的接口與它所裝飾的CExport對象的接口是一致的,保持CExport類的簡單性很重要,否則會使裝飾類擁有一些它們并不需要的功能而難以使用,也使系統(tǒng)付出不必要的代價。設(shè)計時,CExport類應(yīng)集中于定義接口,盡量少地維護數(shù)據(jù),對數(shù)據(jù)的表示和維護應(yīng)延遲到其子類中。當(dāng)CExport類很龐大時,需要考慮使用別的方法來動態(tài)增加裝飾功能。

4 結(jié)束語

設(shè)計模式的使用有效地提高了設(shè)計的質(zhì)量,使整個設(shè)計具有清晰的結(jié)構(gòu)、良好的擴展性和易復(fù)用性。本文提出的數(shù)據(jù)存儲設(shè)計已成功運用于多個項目,對于縮短項目開發(fā)周期具有積極的意義。

[1]Craig Larman.Applying UML and Parrerns[M].北京:機械工業(yè)出版社,2006.

[2]Martin Robert C.敏捷軟件開發(fā):原則、模式與實踐[M].北京:清華大學(xué)出版社,2003.

[3]Booch.Object Solutions:Managing The Object-Oriented Project[M].New York:Addision-Wesley,1996.

[4]Alan Shalloway,Trott James R.Design Patterns Explained:A New Perspective on Object-oriented Design[M].徐言聲譯.北京:人民郵電出版社,2006.

[5]Erich G,Richard H,Ralph J,et al.Design Patterns:Elements of Reusable Object-oriented Software[M].北京:機械工業(yè)出版社,2005.

猜你喜歡
子類職責(zé)代碼
卷入Hohlov算子的某解析雙單葉函數(shù)子類的系數(shù)估計
LNG安全監(jiān)管職責(zé)的探討
滿腔熱血盡職責(zé) 直面疫情寫忠誠
徐鉦淇:“引進來”“走出去”,都是我們的職責(zé)
創(chuàng)世代碼
動漫星空(2018年11期)2018-10-26 02:24:02
創(chuàng)世代碼
動漫星空(2018年2期)2018-10-26 02:11:00
創(chuàng)世代碼
動漫星空(2018年9期)2018-10-26 01:16:48
創(chuàng)世代碼
動漫星空(2018年5期)2018-10-26 01:15:02
關(guān)于對稱共軛點的倒星象函數(shù)某些子類的系數(shù)估計
各級老促會的新職責(zé)
碌曲县| 张家界市| 高台县| 安塞县| 大荔县| 临沂市| 甘泉县| 新郑市| 临潭县| 利津县| 油尖旺区| 开化县| 博湖县| 道真| 开鲁县| 沾化县| 嘉峪关市| 镇安县| 广南县| 阳新县| 上栗县| 盘锦市| 阿合奇县| 安康市| 巫山县| 蒲江县| 黑水县| 金山区| 深水埗区| 鹤壁市| 介休市| 临清市| 饶阳县| 万安县| 河东区| 肥城市| 四川省| 江华| 凉城县| 翼城县| 镇坪县|