設(shè)計(jì)模式&重整技術(shù)運(yùn)用實(shí)例
作者: 點(diǎn)空間 陳國生
Email: bruce123@edirect168.com
日期:2003/09/06
設(shè)計(jì)計(jì)算機(jī)系統(tǒng),最困難的部分是什么?也許你可以找出一大堆的答案,但真正最困難的部分是面對系統(tǒng)功能的改變,這是因?yàn)槲覀儫o法去預(yù)知這些改變。但或許你會(huì)說,那就盡量保持彈性,話雖如此,但我們?nèi)绾沃酪谑裁吹胤奖3謴椥??但如果你的系統(tǒng)無法去應(yīng)付這些改變,那么就只有走向重寫一途,這無疑是一件讓人沮喪的事。在面對這個(gè)問題,我們`必須學(xué)會(huì)用設(shè)計(jì)模式去思考,如果系統(tǒng)的設(shè)計(jì)已經(jīng)僵化了,我們就讓它柔軟下來,如果柔軟不下來,就把它凍結(jié)起來,如果原來設(shè)計(jì)彈性就很好,我們就繼續(xù)擴(kuò)充功能,沒有解決不了的事,以下我們舉個(gè)例子來說明這個(gè)想法。
首先,我們從一個(gè)設(shè)計(jì)模式說起:Facade 外觀模式。我們來談?wù)勥@個(gè)模式,這個(gè)模式的用途是將一個(gè)子系統(tǒng)內(nèi)部的眾多對象統(tǒng)一起來,產(chǎn)生新的接口出來。這讓我想到我們中國有句成語叫:老干新枝。這個(gè)意義是,老干已經(jīng)失去了活力,但為了生存下去,必須產(chǎn)生新的枝芽,這跟一個(gè)已經(jīng)僵化的系統(tǒng)一樣,我們無法期望從原來的枝長出葉子,所以只好另長新芽。
如果一個(gè)系統(tǒng)已經(jīng)糾成一團(tuán),如左圖般的狀態(tài),再繼續(xù)擴(kuò)充功能,或更動(dòng)系統(tǒng)功能,那無疑的是雪上加霜,加速系統(tǒng)的走向死亡之路。由于系統(tǒng)內(nèi)部的對象交互影響,只要移動(dòng)部分的功能,Client 端的使用接口勢必要跟著改變,繼續(xù)使用這樣的系統(tǒng)結(jié)構(gòu),終究有一天會(huì)土崩瓦解。重新去調(diào)整這個(gè)致命的缺點(diǎn),又跟重新改寫沒有兩樣,常常這樣讓人陷入進(jìn)退兩難的窘境。
如果我們可以用設(shè)計(jì)模式去思考解決問題,如右圖將原系統(tǒng)視為一個(gè)子系統(tǒng),使用Facade這個(gè)樣式,重新產(chǎn)生使用接口,將這混亂的局面控制,不再像癌癥一樣繼續(xù)擴(kuò)散開來,內(nèi)部的調(diào)整不再影響Client 的使用接口,那么就可以讓系統(tǒng)取得一個(gè)擴(kuò)充功能的契機(jī)。系統(tǒng)控充功能與內(nèi)部結(jié)構(gòu)的改善,這是兩個(gè)不同的方向,千萬不要攪在一起,也不要同時(shí)去改變,這樣會(huì)使問題更加的復(fù)雜,
接下來,我們來探討一下什么叫重整?Martin Fowler 于書中定義它是一種「在不改變代碼外在行為的前提下對代碼做出修改,以改進(jìn)代碼的內(nèi)部結(jié)構(gòu)」的過程。如果說重整的目的不在于對既有的代碼增加新功能,而只是不影響程序既有功能及正確的執(zhí)行下,改善程序代碼。那么對許多人而言,讓他們感到相當(dāng)疑惑 的是,這種行為是否能帶來任何的益處?重整如果只是改善內(nèi)部結(jié)構(gòu),那顯然是無助于增加效益,所以重整的目的勢必與往后的系統(tǒng)擴(kuò)充功能產(chǎn)生緊密的關(guān)聯(lián)。俗語說:休息是為走更遠(yuǎn)的路,所以沒有重整,也就沒有更遠(yuǎn)的路。而本篇重點(diǎn)是在改善結(jié)構(gòu)跟擴(kuò)充功能這兩個(gè)想法緊密的結(jié)合在一起。也就是說在改變現(xiàn)有結(jié)構(gòu)之后,進(jìn)行系統(tǒng)功能擴(kuò)充,根據(jù)現(xiàn)有的結(jié)構(gòu)加以改善,以符合擴(kuò)充的需要。試想,如果沒有新的需求產(chǎn)生,需要擴(kuò)充功能,又何必大費(fèi)周章的去進(jìn)行重整呢?但是從本篇的范例中,有些范例雖然未擴(kuò)展功能,但經(jīng)過使用樣式設(shè)計(jì)進(jìn)行重整結(jié)構(gòu)的改善,幾乎已經(jīng)可以看見擴(kuò)展新的功能的曙光,這是重整帶來最大的好處。
俗語說:做衣容易,改衣難。這說明一件事,雖然做衣服跟改衣服,用的是同樣的技術(shù),但卻是不同的思維,所以變成了會(huì)做衣服卻不一定會(huì)改衣服。對設(shè)計(jì)系統(tǒng)而言,系統(tǒng)中任何一個(gè)變動(dòng),就像改衣服一樣,學(xué)習(xí)克服這些變動(dòng),才能快速的反應(yīng)變動(dòng)。近年來軟件工程的思維傾向貼近客戶需求,擁抱改變,但這不光是口號而已,在這個(gè)思潮下,背后必須有強(qiáng)而有力的設(shè)計(jì)技術(shù)及思考模式所支撐,因此學(xué)習(xí)這些基本技術(shù)及不斷的磨練你的思考模式,才能去符合這樣的要求。本篇就是基于這樣的想法,將設(shè)計(jì)模式與重整兩個(gè)重要的基本技術(shù)加以結(jié)合運(yùn)用,實(shí)現(xiàn)系統(tǒng)面對改變時(shí),如何去反應(yīng)變動(dòng),及如何讓系統(tǒng)保持適當(dāng)?shù)膹椥浴?/p>
底下,對本篇所提供的實(shí)作范例,作簡單扼要的說明:
范例一:運(yùn)用Observer 觀察者模式解開單元之間的耦合,是重整的典型范例,本范例著眼于系統(tǒng)結(jié)構(gòu)改善,并未擴(kuò)充新功能。
范例二:運(yùn)用Template Method 樣式設(shè)計(jì)數(shù)據(jù)庫的異動(dòng)交易控制,這個(gè)范例架構(gòu)在原系統(tǒng)上面,將原來程序代碼加以凍結(jié),并擴(kuò)展新功能。
范例三:運(yùn)用Factory 工廠模式設(shè)計(jì)多人使用的權(quán)限控制,這個(gè)范例使用替代的方式,在不改變原有功能的前提增加了系統(tǒng)的彈性。
范例一
運(yùn)用Observer 觀察者模式解開單元之間的耦合
作者:陳國生
Email: bruce123@edirect168.com
【解決問題】
在Delphi 的對象中,TForm 是一個(gè)很搶眼的角色,因?yàn)樵谝粋€(gè)Form 當(dāng)中,我們可以輕易的結(jié)合許多不同的對象一起工作,幾乎是無所不能,但是在比較復(fù)雜的系統(tǒng)中,我們必須根據(jù)不同的功能,切割放在不同的Form 上面 ,或者說是在不同單元當(dāng)中。當(dāng)一個(gè)系統(tǒng)存在許多不同單元之后,我們要如何去讓這些單元可以相互合作?使用USES 可以將兩個(gè)不同單元視為一個(gè)單元來使用,但遺憾的是,這種設(shè)計(jì)方式往往會(huì)造成單元之間的耦合性過高,當(dāng)一個(gè)單元變動(dòng)之后,往往其它的單元也會(huì)跟著受影響,而整個(gè)系統(tǒng)也就因此牽一發(fā)而動(dòng)全身了。
當(dāng)然,我們可以透過使用接口讓這個(gè)問題不至于過度的惡化,但仍無法確實(shí)的解決這個(gè)致命的糾纏。因?yàn)橥高^使用接口來運(yùn)作,仍然必須USES這個(gè)單元,當(dāng)這個(gè)單元被取消之后,仍然會(huì)影響其它單元的運(yùn)作。
【面臨問題】
也許,此刻你的程序已經(jīng)陷入這樣致命的糾纏當(dāng)中,我們要如何才能去解開這個(gè)結(jié)呢?
【運(yùn)用技術(shù)】
本范例將運(yùn)用Observer 觀察者樣式,來解決單元之間的糾纏不清。首先我們先來看看這個(gè)觀察樣式定義:觀察者模式定義對象間的一對多的相互關(guān)系,使得一個(gè)對象改變時(shí),其它相關(guān)對象皆可獲得通知并自動(dòng)更新。這個(gè)模式里面,會(huì)有一個(gè)觀察者,及一個(gè)以上的被觀察者,當(dāng)觀察者的狀態(tài)改變時(shí),被觀察者被主動(dòng)的告之,而觀察者負(fù)責(zé)通知,被觀察者卻不用知道觀察者是誰。
從理解一個(gè)抽象概念的,到運(yùn)用在解決問題上面,過程通常不是那么的容易。根據(jù)觀察的樣式提供的概念,其實(shí)Delphi 這個(gè)RAD 已經(jīng)幫我們設(shè)計(jì)許多功能強(qiáng)大的對象,所以重要的是,我們?nèi)绾稳ミ\(yùn)用這個(gè)概念去解決問題,要把焦點(diǎn)放在解決問題上面。
觀察者模式,有點(diǎn)類似Window里面的訊息傳遞機(jī)制,如果我們要實(shí)作這樣的機(jī)制,那么必須要有一個(gè)可以儲(chǔ)存這些訊息及事件的容器型對象。在Delphi 中有許多現(xiàn)成的對象,你無須費(fèi)心的去設(shè)計(jì)這樣的對象,只要找出可以實(shí)踐這樣想法的對象即可,本范例中,我們運(yùn)用TActionList來實(shí)現(xiàn),TActionList 是一個(gè)事件串行,現(xiàn)在就看我們?nèi)绾紊朴眠@個(gè)對象,去達(dá)到訊息傳遞的目的了。
在下面的范例中,我們將實(shí)作一個(gè)橫跨整個(gè)系統(tǒng)的觀察者樣式,解開單元之間的耦合問題。
【實(shí)作范例】
第一步,建立一個(gè)TDataModule,并在DataModule 1上面放置一個(gè)TActionList 的對象。
第二步,分別建立兩個(gè)TForm,F(xiàn)orm1及Form2 ,在Form1,F(xiàn)orm2 各放一個(gè)TEdit 以供測試。
第三步,在TDataModule 增加一個(gè)屬性,myValue:string。
第四步,在TActionLIst 增加一個(gè)TAction 對象,并寫入控制事件:
procedure TDataModule1.Action1Execute(Sender: TObject);
begin
if Form1<>nil then Form1.Edit1.text:=myValue;
end;
第五步,在Form2的Edit1的OnKeyPress 寫入:
procedure TForm2.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
DataModule 1.myValue:=Edit1.text;
DataModule 1.Action1.Execute;
end;
第六步,在Form1激活Form2,然后在Form2的Eedit1 輸入資料,此時(shí)可見Form1.Edit1 同步收到訊息了。
從這個(gè)范例中,可以將Form2視為是一個(gè)觀察者,而Form1 是一個(gè)被觀察者,當(dāng)Form2的TEdit的值改變后,透過事件通知,改變了Form1的TEdit,然而Form2 并無USES Form1 ,也不知道Form1的存在,所以即使Form1消失了,仍然不會(huì)影響Form2的運(yùn)作。
所以,從這個(gè)運(yùn)作架構(gòu)中,我們可以依系統(tǒng)變動(dòng)的需求,不斷的增加控制事件,卻不會(huì)影響單元之間的關(guān)系。
【結(jié) 論】
在一個(gè)大的系統(tǒng)里面,控制單元之間的耦合性非常重要,以上述的范例來說,不論系統(tǒng)如何改變,各個(gè)單元都可以維持正常的運(yùn)作,既相互合作又不會(huì)相互影響,其變動(dòng)姓被有效的控制在一個(gè)事件串行當(dāng)中,當(dāng)單元變動(dòng)時(shí),我們很容易追蹤,且不會(huì)擴(kuò)散到整個(gè)系統(tǒng)。
范例二
運(yùn)用Template Method 樣式設(shè)計(jì)數(shù)據(jù)庫的異動(dòng)交易控制
作者:陳國生
Email: bruce123@edirect168.com
【解決問題】
什么是異動(dòng)交易控制?簡單的說,就是如何確保在資料改變的過程,可以順利的完成,異動(dòng)交易控制最主要的著眼點(diǎn)在于對交易失敗的控制,試想一個(gè)交易,基于某種不可預(yù)期的原因造成程序產(chǎn)生錯(cuò)誤,中途被迫終止交易,那之前已經(jīng)改變的資料算不算數(shù)?如果不算數(shù),那之前已經(jīng)交易的資料怎么辦呢?
舉例來說,一張進(jìn)貨單可能要同時(shí)更新單據(jù)檔及庫存檔,如果中途失敗,可能造成單據(jù)文件有資料而庫存文件沒有更新,要如何才能避免這種嚴(yán)重的錯(cuò)誤呢?那就是必須進(jìn)行異動(dòng)交易的控制,在一個(gè)異動(dòng)交易控制中,只要有一筆交易失敗,那么之前所有交易的資料,將被還原至交易之前。
在Delphi 的Connection 對象已經(jīng)提供了良好的控制程序。以TAdoConnection為例,它的語法格式如下:
try
// 開始進(jìn)行交易控制
adoconnection1.BeginTrans;
// 寫入您的交易程序
.......
.......
.......
// 將交易資料實(shí)際寫入數(shù)據(jù)庫
adoconnection1.CommitTrans;
except
// 如果發(fā)生意外,將之前所有已交易資料還原
adoconnection1.RollbackTrans;
end;
從上面的控制結(jié)構(gòu)來看,它是將一個(gè)交易程序帶入交易控制之中,那么也就是說,如果你原先寫的交易程序如果沒有做這樣的控制,只要加入這樣的控制程序,就可以進(jìn)行異動(dòng)交易。但在程序重整的技術(shù)中,有一點(diǎn)必須要注意,那就是盡量不要去更動(dòng)現(xiàn)有的程序,因?yàn)橐坏└鼊?dòng)程序,就必須重新作測試,因此在不更動(dòng)現(xiàn)有的程序的前提下,我們要如何去修改程序,讓程序具有異動(dòng)交易控制能力呢?
【面臨的問題】
雖然Delphi 已經(jīng)有了很好的解決方式,但是對一些已經(jīng)寫好的交易程序,我們在不變動(dòng)原有的程序代碼,如何進(jìn)行功能的擴(kuò)充呢?
【使用技術(shù)】
這個(gè)案例,我們將利用到重整技術(shù)的概念及樣式設(shè)計(jì)來解決這個(gè)問題。范例中我們會(huì)用到Template Method 這個(gè)樣式來設(shè)計(jì)一個(gè)程序,什么叫Template Method ?它的定義如下:
在父類別中定義一個(gè)算法的骨架,但將一些步驟延遲到其子類別中執(zhí)行。套句話說,一個(gè)人犯罪是要坐牢的,這個(gè)犯罪要坐牢就是一個(gè)樣版,至于做幾年的牢,要看當(dāng)時(shí)犯了什么罪才來決定。
這樣的說法還是很抽象,我們進(jìn)一步說明這個(gè)抽象的概念的運(yùn)用時(shí)機(jī):
利用Template Method 可以定義一些共享的算法,差異性部分則由子類別去實(shí)作,讓一些有差異性的子類別,擁有共同的算法,如此則程序不但有彈性,且易于維護(hù)。
我們應(yīng)該可以想象,異動(dòng)交易控制就是一個(gè)算法,這個(gè)算法會(huì)被利用在許多需要控制異動(dòng)交易的地方,每個(gè)異動(dòng)交易的內(nèi)容是不一樣的,但異動(dòng)控制的運(yùn)算卻是一致的。Template Method 這個(gè)樣式的重點(diǎn)乃在區(qū)分變與不變的地方,將不變的部分寫成骨架,將變的部分保留起來,對于一個(gè)異動(dòng)交易控制程序來說,異動(dòng)交易內(nèi)容是變動(dòng)的部分,而異動(dòng)控的運(yùn)算是不變的部分。
【實(shí)作范例】
在這個(gè)的范例中,我們并沒有使用類別的繼承層級,但卻是運(yùn)用了另一種方式去實(shí)現(xiàn)這個(gè)差異性的部分,只要是考慮與現(xiàn)有程序的協(xié)調(diào)問題,至于使用類別層級的方式,在結(jié)論中亦有說明其做法。
首先,在TAdoconnect所在的控制模塊中,增加一個(gè)程序,這個(gè)程序跟上述的異動(dòng)控制結(jié)構(gòu)差不多,只加入了一個(gè)TrandProc的事件,在這個(gè)事件中,我們將允許執(zhí)行一些差異的運(yùn)算,因此很簡單的,我們已經(jīng)將Template Method 這個(gè)樣式運(yùn)用在程序設(shè)計(jì)中了。
function TDmConNection.RunTrans( TransProc:TNotifyEvent):boolean;
begin
try
adoconnection1.BeginTrans;
transProc(self);
adoconnection1.CommitTrans;
result:=true;
except
adoconnection1.RollbackTrans;
result:=false;
end;
end;
接下來,我們來看一下,如何運(yùn)用這個(gè)樣式來解決問提呢,假設(shè)你有一個(gè)異動(dòng)程序是這樣:
// 異動(dòng)程序
procedure TForm1.rename(sender: TObject);
var
n:integer;
begin
adodataset1.First;
for n:=0 to adodataset1.RecordCount-1 do begin
if adodataset1[‘使用者‘]=‘bruce‘ then begin
adodataset1.edit;
adodataset1[‘異動(dòng)‘]:=checkbox1.checked;
adodataset1.post;
end;
adodataset1.next;
end;
end;
現(xiàn)在,我們要為這個(gè)異動(dòng)程序增加異動(dòng)控能力,只要增加這樣的一個(gè)程序就可以了:
procedure TForm1.Button1Click(Sender: TObject);
begin
if not dmconnection.RunTrans( rename )then
application.MessageBox(‘執(zhí)行失敗‘,‘錯(cuò)誤‘,0);
end;
把現(xiàn)有的異動(dòng)程序當(dāng)成一個(gè)參數(shù),傳至RunTrans 這個(gè)異動(dòng)交易控制的運(yùn)算中,就大功告成。
【結(jié) 論】
這個(gè)范例運(yùn)用Template Method 樣式,避免修改已經(jīng)完成的程序,同時(shí)又可以增加系統(tǒng)的功能。當(dāng)然這個(gè)范例,也可以運(yùn)用類別繼承的方式來實(shí)現(xiàn),其寫作的方式,與上述的范例,亦相去無幾,原事件改成宣告一個(gè)虛擬的程序,并在子類別中去實(shí)作這個(gè)程序即可,運(yùn)用的概念是一樣的,這正是所謂戲法人人會(huì)變,巧妙各有不同,融會(huì)貫通之后就可以運(yùn)用自如了。
范例三
運(yùn)用Factory 工廠模式設(shè)計(jì)多人使用的權(quán)限控制
作者:陳國生
Email: bruce123@edirect168.com
【解決問題】
在一個(gè)多人使用的系統(tǒng)中,根據(jù)不同的使用者,必須設(shè)計(jì)出不同的使用權(quán)限,要設(shè)計(jì)這樣的權(quán)限控管機(jī)制,很顯然相當(dāng)復(fù)雜而且繁瑣。因此,如何使用一個(gè)簡單又容易維護(hù)的方式進(jìn)行系統(tǒng)設(shè)計(jì)?在軟件設(shè)計(jì)領(lǐng)域里面,簡單就是美,這是在靈活塑模里面的一個(gè)宣言,追求簡單,其實(shí)不簡單,同樣的一個(gè)問題,有千百種解法,如何使用一個(gè)簡單又有彈性的設(shè)計(jì),是程序設(shè)計(jì)者追求的極致,本范例的重點(diǎn)就是要具體實(shí)踐這個(gè)目標(biāo)。
【面臨問題】
對已經(jīng)寫好的程序,我們不希望修改,因此如何以擴(kuò)充功能的方法,將此權(quán)限控制的功能加入系統(tǒng)?
【運(yùn)用技術(shù)】
在重整技術(shù)中,有一個(gè)重要的原則,就是不要去更動(dòng)已經(jīng)設(shè)計(jì)好的程序,因此我們將設(shè)計(jì)一個(gè)即插即用的單元,為系統(tǒng)擴(kuò)充多人使用的控管機(jī)制,因此在這個(gè)構(gòu)想下,我們運(yùn)用Factory 工廠模式的設(shè)計(jì)樣式來實(shí)現(xiàn)這個(gè)設(shè)計(jì)。
什么是Factory 工廠模式?工廠模式可以依實(shí)際需要,適時(shí)的產(chǎn)生我們所需要的對象,在于無法確定使用何種對象的時(shí)候非常好用。在Delphi 中已經(jīng)內(nèi)建許多不同類型的對象,我們可以隨手取用,所以設(shè)計(jì)一個(gè)工廠模式可以說非常的簡單。對象工廠本身有許多變形,如工廠方法( Factory Method ),抽象工廠( Abstract Factory ),雛形( Prototype ) 等等... 皆是。
現(xiàn)在,我們假設(shè)每一個(gè)使用者登入時(shí),會(huì)對應(yīng)到一個(gè)權(quán)限對象,然后針對這個(gè)對象去設(shè)計(jì)使用權(quán)限即可。換句話說,也就是說讓不同的使用者對應(yīng)到不同的對象上面,再運(yùn)用工廠模式,根據(jù)不同的使用者,自動(dòng)產(chǎn)生不同的對象,如此便可達(dá)到權(quán)限控制的目的。
當(dāng)然,控制使用的權(quán)限,依控管方式不同,會(huì)方法有很多種,下面范例將提供其中一種控管方法。
【范例實(shí)作】
第一步:使用一個(gè)TDataModule 來存放一些TMainMenu對象。
第二步:TMainMenu 的數(shù)量根據(jù)使用者的多寡而定。
第三步:增加一個(gè)TActionList對象,將所有可執(zhí)行程序統(tǒng)一交由TActionList 控管。
第四步:根據(jù)不同的使用權(quán)限,將TActionList 里面的TAction 指定至各個(gè)不同的TMainMenu 里面的Action 屬性。
以上四個(gè)步驟,在Delphi 里面都可以可視化的完成,除了TAction里面的OnExecute必須動(dòng)手寫入欲執(zhí)行的功能之外。
至此,我們已經(jīng)把準(zhǔn)備對應(yīng)到使用者的權(quán)限對象TMainMenu 都設(shè)計(jì)完成了,接下來只要根據(jù)不同的使用者輸出不同對象即可,這部分要如何設(shè)計(jì)呢?首先我在TDataNodule 的OnCreate事件中,加入判斷使用者的功能,并輸出對象:
procedure TDataModule1.DataModuleCreate(Sender: TObject);
var
MyMainMenu:TMainMenu;
User:string;
begin
// 根據(jù)不同使用者,取得不同的TMainMenu對象,以下以此類推...
User:=ParamStr(1);
if User=‘001‘ then MyMainMenu:=MainMenu1;
if User=‘002‘ then MyMainMenu:=MainMenu2;
.....
.....
// 接下來輸出對象至主畫面
Application.MainForm.Menu:=MyMainMenu;
end;
以上完成之后,最后的一個(gè)步驟是把TDataModule 在項(xiàng)目中自動(dòng)建構(gòu)起來,由于設(shè)計(jì)上是自動(dòng)輸出對象至MainForm,所以TDataModule 的建構(gòu)必須在MainForm 之后,這樣就算大功告成了。注意:本范例無處理User 登錄的功能,系使用傳遞參數(shù)的方法來判斷使用者,這部分請自行參考變化。
【結(jié) 論】
工廠模式的對象產(chǎn)生方式,可以動(dòng)態(tài)產(chǎn)生,也可以靜態(tài)建立,Delphi 中有兩個(gè)對象可以很方便的存放這些事先建好的對象,一個(gè)是TForm ,一個(gè)TDataModule,在本范例中,是利用TDatamodule 存放事先建立好的對象,讓Client 端可以很方便的取得這些對象。
靜態(tài)建立的好處,在于可以利用Delphi 的可視化設(shè)計(jì)環(huán)境去建構(gòu)這些對象,因此運(yùn)用工廠模式及善用Delphi 現(xiàn)有的對象來設(shè)計(jì),可以減少許多的程序代碼,增加系統(tǒng)執(zhí)行的穩(wěn)定度,程序代碼寫的愈多,出錯(cuò)的機(jī)會(huì)就愈大,相對的系統(tǒng)也不容易維護(hù),這應(yīng)該是簡單就是美的真諦吧!