,,,
(1. 大慶油田有限責(zé)任公司測試技術(shù)服務(wù)分公司 黑龍江 大慶 163412;2. 東北石油大學(xué)電氣信息工程學(xué)院 黑龍江 大慶 163318)
相對于大多數(shù)的商用軟件來說,測井軟件的需求變化是非??斓?。這就要求測井軟件必須能夠及時修改,增添新的功能,適應(yīng)新的變化,即對其擴展性及復(fù)用性提出了非常高的要求。
測井軟件的一個主要功能就是數(shù)據(jù)采集和控制,當(dāng)?shù)孛嫦到y(tǒng)的硬件板卡改變或增減時,軟件就需要相應(yīng)的修改。另外,隨著測井項目的不斷增加,軟件功能和要求也會越來越多。同時,隨著操作系統(tǒng)的升級換代,對軟件的兼容性和可移植性也提出了較高的要求。
以上需求的變化,大大增加了測井軟件的開發(fā)難度。嚴(yán)重時,為了增加某一功能,軟件可能就不得不重新設(shè)計。如何適應(yīng)需求的變化,最大程度的實現(xiàn)軟件復(fù)用,已成為軟件人員迫切需要解決的問題。
設(shè)計模式[1-4]的概念最早來源于建筑學(xué),由建筑師Alexander提出來的。它是一套被反復(fù)使用,經(jīng)過分類編目的,代碼設(shè)計經(jīng)驗的總結(jié)。使用設(shè)計模式是為了可重用設(shè)計,它可以被用于新的語境中,并為使用者提供一些處理新情況的建議。設(shè)計模式使代碼編制真正工程化[5],是軟件工程的基石。
設(shè)計模式可以幫助人們復(fù)用現(xiàn)有的設(shè)計結(jié)構(gòu)和體系結(jié)構(gòu)[6],并且實現(xiàn)起來具有過程簡單,方便的特點。
1)模式名
助記名,一個有助記憶的名稱,將模式中的問題、解決方案以及達到的效果用一(兩)個詞描述出來。應(yīng)用設(shè)計模式,我們可以進行較高的抽象層次設(shè)計。模式名除了有助于我們思考之外,還可以使我們更方便的與其他設(shè)計者進行設(shè)計思想及設(shè)計結(jié)果的交流。
2)問題
它可能指出了設(shè)計中存在現(xiàn)有問題的原因,以及可能產(chǎn)生的后果,也有可能描述了需要增加的設(shè)計問題,也有可能描述了一些類或?qū)ο蠼Y(jié)構(gòu),它們是導(dǎo)致設(shè)計不靈活的主要原因。有時候,問題部分會包括使用模式必須滿足的一系列先決條件。
3)解決方案
描述的是設(shè)計的組成部分之間的相互關(guān)系及各自的職責(zé)和協(xié)作方式。模式就好比是一個設(shè)計模板,可應(yīng)用于多種不同場合,所以解決方案并不是一個特定而具體的設(shè)計或?qū)崿F(xiàn),它是對設(shè)計問題的抽象描述,以及指出怎樣用一個具有一般意義的元素組合(類或?qū)ο蠼M合)來解決這個問題。
4)效果
采用設(shè)計模式后的應(yīng)用效果及使用模式設(shè)計過程中應(yīng)權(quán)衡的問題。它包括模式效果和軟件效果兩個方面[7-9]。在進行設(shè)計決策時,模式效果雖然不常被提到,但它在評價設(shè)計選擇和理解使用模式的代價及好處等方面卻具有重要意義。一般情況下,軟件效果表述的是語言和實現(xiàn)問題,是在時間和空間的衡量。
設(shè)計模式通常分為兩類[10,11]:一是按照設(shè)計目的不同進行分類,該類模式主要以具體完成的工作作為分類標(biāo)準(zhǔn);二是按照處理范圍不同進行分類,該類模式主要以用于類還是用于對象實例作為分類標(biāo)準(zhǔn)。按照第一種分類方式,設(shè)計模式可分為創(chuàng)建模式、結(jié)構(gòu)模式和行為模式三大類。按照第二種分類方式,設(shè)計模式可分為類模式和對象模式兩大類。具體設(shè)計模式分類如表1所示。
表1 設(shè)計模式分類表
各種模式均有其自身特點和適用范圍,所以在選取模式前應(yīng)充分了解模式的內(nèi)涵及側(cè)重點,發(fā)掘出不同模式的適用規(guī)律[12,13]。
選擇合適的軟件設(shè)計模式通常需要考慮以下幾個方面:
1)熟練掌握各種設(shè)計模式的處理范圍;
2)瀏覽模式的意圖部分;
3)研究模式之間如何相互聯(lián)系;
4)將目的相同模式進行對比研究;
5)明確重新進行設(shè)計的意圖;
6)明確設(shè)計中的可變元素。
一般的選擇步驟如下:
1)對所要解決的問題進行抽象,并劃分適當(dāng)?shù)念愋停?/p>
2)根據(jù)問題類型選擇適合的設(shè)計模式;
3)規(guī)劃問題和匹配模式;
4)對選取的模式進行變體,即對模式的原始結(jié)構(gòu)進行修改和擴展,以解決具體問題;
5)設(shè)計并細化所需的軟件體系結(jié)構(gòu);
6)對設(shè)計質(zhì)量進行度量。
測井軟件的用戶需求是變化的,因而軟件的修改是不可避免的。需求的變化主要表現(xiàn)在測井地面系統(tǒng)硬件的改動及測井項目的增加,這些變化因素在軟件的設(shè)計中必須重點考慮。針對上述實際情況,在軟件設(shè)計過程中采用了設(shè)計模式[14,15],則主要是因為其具有適應(yīng)需求的變化的特點。此外,由于設(shè)計模式的引入,使得測井軟件系統(tǒng)不僅具有更好的可復(fù)用性,其擴展性和維護性也變得更加容易。
測井軟件的一項主要功能是實現(xiàn)實時的數(shù)據(jù)采集。這就要求軟件與具體的采集板卡發(fā)生交互,即下傳控制指令,上傳采集數(shù)據(jù)。另外,實時采集軟件一般采用多線程設(shè)計,使得多個線程可能同時操作同一采集板卡或一個線程控制多個采集板卡。對于測井軟件來說,地面硬件系統(tǒng)具有唯一性,但對于硬件系統(tǒng)自身來講,它所包含的采集板卡的數(shù)量和功能是可變的。
下面以超越地面系統(tǒng)硬件接口組件設(shè)計為例,介紹一下如何將設(shè)計模式應(yīng)用于測井軟件的設(shè)計中,以提高軟件質(zhì)量。
定義: 保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。適用于在一個系統(tǒng)要求一個類只有一個實例時才應(yīng)當(dāng)使用單例模式。
這個唯一實例應(yīng)該是通過子類化可擴展的,并且客戶應(yīng)該無需更改代碼就能使用一個擴展的實例時。
優(yōu)點:對唯一實例的受控訪問;自行實例化并向整個系統(tǒng)提供這個實例。單件模式取代了全局對象,降低了代碼耦合度,便于程序修改和維護。
針對超越地面系統(tǒng)硬件的唯一性,以前的測井軟件設(shè)計常常將硬件接口對象定義為一個全局變量,而全局變量是程序員心中永遠的痛。主要問題包括:
1)變量名沖突,增加管理成本。
2)耦合度增加。
3)單個實例問題。全局變量不能阻止程序員定義一個類的多個對象實例。在一個多人參與、并行開發(fā)的大型項目中,這也會增加很多管理上的負擔(dān)。
4)初始化順序。全局變量不可能保證相互之間遵循特定的初始化順序,這完全由編譯器決定。
5)多線程訪問。當(dāng)多個并發(fā)的線程都需要訪問某些全局變量時,我們必須使用各種同步機制,小心地保護這些全局變量,以免陷入并發(fā)沖突的泥潭。
設(shè)計模式中的單件模式就很好地解決了此類問題,它即保證了對象的唯一性,也避免了全局變量帶來的問題。單件模式就是以一個類只有一個對象實例為設(shè)計目的,并提供一個訪問該對象實例的全局訪問點。程序員不能通過類的構(gòu)造函數(shù)獲得對象實例(因為構(gòu)造函數(shù)聲明為private或protected類型),但可以從該類提供的靜態(tài)成員函數(shù)得到該類唯一的對象實例指針或引用。從某種意義上說,我們可以把這個對象實例看做一個隱藏在單件類內(nèi)部的“隱式全局變量”。因此在超越測井軟件的硬件接口設(shè)計中采用了單件模式,程序部分代碼如下:
class CExceedHard : public CHardInterface
{
private:
CExceedHard(void);
public:
~CExceedHard(void);
static CHardInterface* GetInstance(void);
static void DelInstance(void);
}
定義:定義一個創(chuàng)建對象的抽象類(接口),但是卻讓子類來決定具體實例化哪一個類。當(dāng)一個類無法預(yù)料要創(chuàng)建哪種類的對象或是一個類需要由子類來指定創(chuàng)建的對象時,我們就需要用到該模式了。工廠方法模式可以根據(jù)不同的條件產(chǎn)生不同的實例,但這些不同的實例通常是屬于相同的類型,并具有共同的父類。
優(yōu)點:當(dāng)系統(tǒng)擴展需要添加新的產(chǎn)品對象時,僅僅需要添加一個具體對象以及一個具體工廠對象,原有工廠對象不需要進行任何修改,也不需要修改客戶端,很好的符合了“開放-封閉”原則。
超越地面系統(tǒng)硬件接口組件中聚合多個采集板卡對象,這些采集板卡對象是否都需要創(chuàng)建,還是選擇性的創(chuàng)建幾個,是由組件根據(jù)測井項目的需要來動態(tài)創(chuàng)建的。硬件接口組件的調(diào)用者不知道,也無需知道具體要創(chuàng)建哪些采集板卡對象。這種方式可以更好地適應(yīng)未來采集板卡數(shù)量的改變及功能的變化。
設(shè)計模式中的工廠方法模式可以很好地解決此類問題。工廠方法模式以定義一個用于創(chuàng)建對象的接口為設(shè)計目的,讓子類決定實例化哪一個類,將實例化延遲到其子類。對應(yīng)的問題范疇就是一個類需要實例化另一個類的派生類,但不知道具體是哪個派生類。工廠方法模式允許派生類來做出決定。該模式在定義框架的過程中很常用。這是因為框架存在于一個抽象的層次上。通常,它們不知道,而且也不應(yīng)該關(guān)心特定對象的實例化。它們需要將特定對象的決策推遲框架的用戶。
在超越地面系統(tǒng)硬件接口組件設(shè)計中,就是采用工廠方法模式來動態(tài)創(chuàng)建需要的板卡對象。即根據(jù)測井項目需要的測量通道來動態(tài)創(chuàng)建含有此通道的采集板卡對象,而無需由程序員在代碼中明確創(chuàng)建某一類型的采集板卡對象。這種實現(xiàn)方式也體現(xiàn)出了設(shè)計模式的設(shè)計原則和理念,即針對接口編程,而不要針對實現(xiàn)編程,根本的意圖是適應(yīng)需求變化。程序的部分代碼如下:
short CExceedHard::AddChannel(CString strName, UINT uChannelSize, UINT uBufferLen, DataType iDataType)
{
CBDChannel* pChannel = new CBDChannel(strName, uChannelSize, uBufferLen);
if(pChannel != NULL)
{
BDChannelInfo* pChInfo = NULL;
for(int i=0; i { pChInfo = (BDChannelInfo*)m_inherentChannelInfoList.GetAt(i); if(pChInfo != NULL) { if(strName == pChInfo->strChannelName) { CString strBoardName = pChInfo->strBoardName; if(strBoardName == _T("SC58301A")) pBoard = new CBD58301A(); else if(strBoardName == _T("SC58112")) pBoard = new CBD58112(); else if(strBoardName == _T("SC58114")) pBoard = new CBD58114(); if(pBoard != NULL) { m_usedBoardList.Add(pBoard); return HD_SUCCESS;}}}}}} 采用該種設(shè)計的優(yōu)點:當(dāng)系統(tǒng)擴展需要添加新的產(chǎn)品對象時,僅僅需要添加一個具體對象以及一個具體工廠對象,原有工廠對象不需要進行任何修改,也不需要修改客戶端,很好的符合了“開放-封閉”原則。 設(shè)計模式既簡單又復(fù)雜。使用設(shè)計模式要求我們添加更多的類,進行更多的設(shè)計工作,這是設(shè)計模式復(fù)雜的一面。它提醒我們,設(shè)計模式只應(yīng)對變化或可能變化的部分使用,對于不變的部分濫用就會造成“過度設(shè)計”。由于超越地面系統(tǒng)的測井軟件具有用戶需求變化,軟件修改不可避免等特點。因此,在軟件設(shè)計過程中采用設(shè)計模式,此外,由于設(shè)計模式的引入,使得測井軟件系統(tǒng)不僅具有更好的可復(fù)用性,其擴展性和維護性也變得更加容易。實現(xiàn)了面對變化的需求時,我們只需要修改很少的代碼,就可以滿足新的需求,這是設(shè)計模式簡單的一面,它可以大幅度簡化我們后續(xù)的開發(fā)和維護工作。 設(shè)計模式最根本的意圖就是適應(yīng)需求變化,這一點正是測井軟件急需解決而不好解決的問題。另外,設(shè)計模式可以有效地提高軟件的設(shè)計和代碼復(fù)用性,便于成果的繼承,事半功倍。因此,學(xué)習(xí)運用設(shè)計模式是開發(fā)高質(zhì)量測井軟件的必由之路,前景廣闊。 [1] GAMMA E.設(shè)計模式—可復(fù)用面向?qū)ο筌浖幕A(chǔ)[M].李英軍,譯.北京:機械工業(yè)出版社,2000:55-75. [2] JACOBSON I.The unified modeling language development process [M].Boston: Addison Wesley, 1998:141-152. [3] MIKKONEN T.Formalizing design patterns[A].Proceedings of International Conference on Software Engineering [C].New York: IEEE Computer Society Press, 1998:115-124. [4] GAMMA E. Design patterns: elements of reusable object-oriented systems[M] . Boston: Addison Wesley,1995:75-90. [5] 萬劍怡,薛錦云.使用規(guī)范匹配實現(xiàn)設(shè)計模式的自動獲取[J].小型微型計算機系統(tǒng),2002,23(3):326-329. [6] 張世博,周樹杰,閔艷.JAVA程序開發(fā)中的設(shè)計模式[J].微型電腦應(yīng)用, 2002, 18(9): 45-47. [7] 鐘茂生,王明文.軟件設(shè)計模式及其使用[J].計算機應(yīng)用,2002,22(8):32-35. [8] 廖志剛,李增智.設(shè)計模式在系統(tǒng)中的應(yīng)用[J].計算機工程與應(yīng)用,2002, (12): 7-10. [9] GAMMA E. Design patterns elements of reusable object-oriented software[M].北京:機械工業(yè)出版社,2002:124-130. [10] 童立,馬遠良.設(shè)計模式在基于組件的框架設(shè)計中的應(yīng)用[J].計算機工程與應(yīng)用,2002, (17): 123-128. [11] ALUR D.Core J2EE patterns[M]. 北京:機械工業(yè)出版社,2002:89-120. [12] ALAN SHALLOWAY & JAMES R. TROTT.設(shè)計模式精解[M].清華大學(xué)出版社,2004,12:1-238. [13] 王詠武 王詠剛.道法自然-面向?qū)ο髮嵺`指南[M].電子工業(yè)出版社,2004:10,1-432. [14] 劉海巖.設(shè)計模式及其在軟件設(shè)計中的應(yīng)用研究[J].西安交通大學(xué)學(xué)報,2005,39(10):1043-1047. [15] ECKEL B.Java 編程思想(第二版)[M].侯捷,譯.北京:機械工業(yè)出版社,2002:5-120.3 結(jié)束語