湯谷云
【摘 要】面向?qū)ο筌浖O(shè)計時,關(guān)鍵是構(gòu)建合適的類及確定各個類之間的結(jié)構(gòu)關(guān)系。設(shè)計模式在某種程度上來說就是引導(dǎo)創(chuàng)建合適的類,確定合理類間關(guān)系的模板。在實踐過程中,結(jié)合實際應(yīng)用,采用模式思維方式引導(dǎo),對分析找到合適的類,選擇合理的類間關(guān)系來實現(xiàn)面向?qū)ο蟮某绦蛟O(shè)計起到了非常好的效果。掌握設(shè)計模式的思想為設(shè)計出可復(fù)用易維護(hù)面向?qū)ο蟪绦蛱峁┝酥匾乃伎挤较?,對?qiáng)化面向?qū)ο笏枷?,建立合理的面向?qū)ο蟪绦蚣軜?gòu)提供了重要保證。
【關(guān)鍵詞】設(shè)計模式;面向?qū)ο螅还δ茴?;類間關(guān)系
【中圖分類號】TP311 【文獻(xiàn)標(biāo)識碼】A 【文章編號】1674-0688(2018)02-0161-03
0 引言
面向?qū)ο蟮某绦蛟O(shè)計的比較重要的思路在于設(shè)計類并確定類間的關(guān)系。面向?qū)ο蟮膽?yīng)用程序一般應(yīng)由多個類構(gòu)成,這多個類劃分成兩大塊,如圖1所示。
其中,主類決定了程序運行時的界面(圖形界面或字符界面),通常稱主類為用戶邏輯(或界面邏輯),而系統(tǒng)中其他非主類能完成一定的功能稱為業(yè)務(wù)邏輯,也可稱為功能類。在實踐過程中,一個軟件系統(tǒng)需要多個功能類,而多個功能類不能是一盤散沙,必須有一個合理的組織結(jié)構(gòu)才能穩(wěn)定并發(fā)揮各自的作用,這跟日常生活中各種單位部門間都有一個合理的組織結(jié)構(gòu)意義相同。因此,從功能類這一部分來說先要有一個合理的組織結(jié)構(gòu),這就是讓各個類之間建立起一定的關(guān)系。
1 類間關(guān)系分析
確定類間的關(guān)系是面向?qū)ο蟪绦蛟O(shè)計的一個難點。類的關(guān)系建立起功能類間的組織結(jié)構(gòu),使各個類各行其職,協(xié)同工作,完成任務(wù)。類間的關(guān)系有泛化、實現(xiàn)、依賴、關(guān)聯(lián),關(guān)聯(lián)又可以進(jìn)一步細(xì)化為聚合和組合。如果不能確定一個關(guān)系是聚合關(guān)系或者組合關(guān)系,可以把這兩種關(guān)系歸結(jié)成關(guān)聯(lián)關(guān)系;以Java為例,實現(xiàn)關(guān)聯(lián)、聚合和組合關(guān)系時,它們的語法特征都是一樣,都表現(xiàn)為一個類是另一個類的屬性。
從Java語法角度來看,關(guān)聯(lián)關(guān)系表現(xiàn)為一個類是另一個類的屬性,依賴則表現(xiàn)為一個類是另一個類中方法的局部變量或參數(shù)。確定類間的關(guān)系是關(guān)聯(lián)還是依賴有時不影響程序的執(zhí)行,甚至對程序的質(zhì)量影響也不大,這就造成了對兩種關(guān)系使用的不確定性。實際上,要準(zhǔn)確地使用這兩種關(guān)系,必須認(rèn)清關(guān)系的本質(zhì)。若干年前,中國是一個自行車的王國,大多數(shù)人都擁有屬于自己的自行車,這時人和自行車的關(guān)系可以理解成一種關(guān)聯(lián)關(guān)系,而如今共享單車的出現(xiàn)使得個人不必?fù)碛凶约旱淖孕熊?,但是在需要的時候可以使用共享自行車,用完之后共享自行車又和自己無關(guān)了,這時人和自行車的關(guān)系就可理解成依賴關(guān)系。也就是說,自行車屬于自己的,可以長期使用就是關(guān)聯(lián)關(guān)系。自行車是借來用,它不屬于自己,只能是暫時使用一下,就是一種依賴關(guān)系。
同樣從Java語法角度來看,理解泛化、實現(xiàn)關(guān)系比較容易和直接,分別用關(guān)鍵詞extends和implements完成關(guān)系的確定。與關(guān)聯(lián)和依賴類似,究竟使用泛化還是實現(xiàn),同樣在某些時候選擇任何一種也是不影響程序質(zhì)量與執(zhí)行的,實際項目設(shè)計時也存在著一種不確定性,因此必須從語義上來理解泛化和實現(xiàn)關(guān)系。在Java中,泛化關(guān)系是一種層次的結(jié)構(gòu),頂層往往是從Java抽象類開始的,而實現(xiàn)關(guān)系也是一種層次結(jié)構(gòu),而它的頂層是從Java接口開始的。
上述兩圖中的實現(xiàn)關(guān)系中頂層為接口,它針對的下層類之間可以是相關(guān)的類,如圖2所示;也可以是毫不相干的類,如圖3所示;但對于泛化關(guān)系來說,下層類之間是有一定相關(guān)性的,也就是說圖2的接口IAction是可以用抽象類來替代,而圖3中的接口Ifuncation用抽象類替代演變成泛化關(guān)系是不合適的。由此可見,實現(xiàn)關(guān)系比泛化關(guān)系具有更好的擴(kuò)展性。
2 利用模式思維解決難點
在進(jìn)行面向?qū)ο筌浖O(shè)計時,其中一個難點是去發(fā)現(xiàn)合適的類。要從一個具體的應(yīng)用項目中去分析和找到合適的類,另一個難點是確定各個類之間的結(jié)構(gòu)關(guān)系,這些決定了一個系統(tǒng)的可復(fù)用、易維護(hù)等特性。而設(shè)計模式就是記錄面向?qū)ο筌浖脑O(shè)計經(jīng)驗,每個設(shè)計模式是針對某類問題解決方案,實際上就是引導(dǎo)如何創(chuàng)建合適的類,如何確定類間關(guān)系的模板。在軟件設(shè)計過程中,并不是每個項目都必須套用設(shè)計模式,都有合適的設(shè)計模式來解決,但在熟悉了設(shè)計模式思想并了解了一些模式后,就能運用模式思想和方法來引導(dǎo)設(shè)計,準(zhǔn)確地發(fā)現(xiàn)合適的類,選擇合適的類間關(guān)系。以下面的實際問題為例,結(jié)合具體的設(shè)計模式進(jìn)行引導(dǎo)分析。
某高校教師指導(dǎo)畢業(yè)設(shè)計論文工作量的計算辦法折合標(biāo)準(zhǔn)課時Y2:
NΧW N0≤N
Y2=N0ΧW+(N-N0)ΧWΧ0.8 N01.4N0ΧW+(N-1.5N0)ΧWΧ0.5 1.5N0
public float getWorkLoad(int num,int n0){
float y2=0.0f;
y2=num*W;
return y2;
}
}
class T2 implements TeachingLoad{
public float getWorkLoad(int num,int n0){
float y2=0.0f;
y2=n0*W+(num-n0)*W*0.8f;
return y2;
}
}
class T3 implements TeachingLoad{
public float getWorkLoad(int num,int n0){
float y2=0.0f;
y2=1.4f*n0*W+(num-1.5f*n0)*W*0.5f;
return y2;
}
}
class T {
TeachingLoad teacher;
int flag;//表示文科或理科
int n0;
int num;//表示實際帶的學(xué)生人數(shù)
public T(int flag,int num ){
if(flag==0)
n0=8;
if(flag==1)
n0=6;
this.num=num;
}
public float getArithmetic()
if(num<=n0)
teacher=new T1();
else if(num<=1.5f*n0)
teacher=new T2();
else if(num<=2*n0)
teacher=new T3();
return teacher.getWorkLoad(num,n0);
}
}
從類圖中可以看出,這種設(shè)計方法滿足了軟件設(shè)計的開閉原則,TeachingLoad接口起到了穩(wěn)定系統(tǒng)的作用,實現(xiàn)了可復(fù)用,它的實現(xiàn)類T1、T2、T3滿足了不同的用戶需求,同時方便插拔操作,相互之間不受影響,實現(xiàn)了易維護(hù)。
3 總結(jié)
如果不以設(shè)計模式為引導(dǎo),這類問題常規(guī)的解決辦法如圖5所示。
class TeachingLoad{
final int W=8;
public float getWorkLoad(int num,int n0){
float y2=0.0f;
if(num<=n0)
y2=num*W;
else if(num<=1.5f*n0)
y2=n0*W+(num-n0)*W*0.8f;
else if(num<=2*n0)
y2=1.4f*n0*W+(num-1.5f*n0)*W*0.5f;
return y2;
}
}
這樣的架構(gòu)盡管體現(xiàn)出了一部分面向?qū)ο蟮乃悸?,但其中缺失了軟件設(shè)計的原則:如開閉原則、面向抽象、面向接口編程等。設(shè)計模式是面向?qū)ο筌浖脑O(shè)計經(jīng)驗,每個設(shè)計模式是針對某類問題解決方案,借助于設(shè)計模式,可以合理地從問題中提取合理的類,確定合適的類間關(guān)系,從而快速完成設(shè)計,是提高代碼質(zhì)量的重要途徑。需要說明的是,實際應(yīng)用中并不是每個項目都必須套用設(shè)計模式,都有合適的設(shè)計模式來解決,但在熟悉了設(shè)計模式思想并了解了一些模式后,對強(qiáng)化面向?qū)ο笏枷?,建立合理的面向?qū)ο蟪绦蚣軜?gòu)提供了思路,對提升程序的可復(fù)用易維護(hù)特性提供了重要保證。
參 考 文 獻(xiàn)
[1]耿祥義.Java2實用教程[M].第5版.北京:清華大學(xué)出版社,2017.
[2]于衛(wèi)紅.Java設(shè)計模式[M].北京:清華大學(xué)出版社,
2016.
[3]王宗亮.Java程序設(shè)計任務(wù)驅(qū)動式實訓(xùn)教程一[M]. 第2版.北京:清華大學(xué)出版社,2016.