敏捷軟件開(kāi)發(fā) 讀書(shū)筆記 (3)——OO五大原則(2.OCP——開(kāi)閉原則)
開(kāi)閉原則很簡(jiǎn)單,一句話:“Closed for Modification; Open for Extension”——“對(duì)變更關(guān)閉;對(duì)擴(kuò)展開(kāi)放”。開(kāi)閉原則其實(shí)沒(méi)什么好講的,我將其歸結(jié)為一個(gè)高層次的設(shè)計(jì)總則。就這一點(diǎn)來(lái)講,OCP的地位應(yīng)該比SRP優(yōu)先。
OCP的動(dòng)機(jī)很簡(jiǎn)單:軟件是變化的。不論是優(yōu)質(zhì)的設(shè)計(jì)還是低劣的設(shè)計(jì)都無(wú)法回避這一問(wèn)題。OCP說(shuō)明了軟件設(shè)計(jì)應(yīng)該盡可能地使架構(gòu)穩(wěn)定而又容易滿足不同的需求。
為什么要OCP?答案也很簡(jiǎn)單——重用。
“重用”,并不是什么軟件工程的專業(yè)詞匯,它是工程界所共用的詞匯。早在軟件出現(xiàn)前,工程師們就在實(shí)踐“重用”了。比如機(jī)械產(chǎn)品,通過(guò)零部件的組裝得到最終的能夠使用的工具。由于機(jī)械部件的設(shè)計(jì)和制造過(guò)程是極其復(fù)雜的,所以互換性是一個(gè)重要的特性。一輛車(chē)可以用不同的發(fā)動(dòng)機(jī)、不同的變速箱、不同的輪胎……很多東西我們直接買(mǎi)來(lái)裝上就可以了。這也是一個(gè)OCP的例子。(可能是由于我是搞機(jī)械出身的吧,所以就舉些機(jī)械方面的例子^_^)。
如何在OO中引入OCP原則?把對(duì)實(shí)體的依賴改為對(duì)抽象的依賴就行了。下面的例子說(shuō)明了這個(gè)過(guò)程:
05賽季的時(shí)候,一輛F1賽車(chē)有一臺(tái)V10引擎。但是到了06賽季,國(guó)際汽聯(lián)修改了規(guī)則,一輛F1賽車(chē)只能安裝一臺(tái)V8引擎。車(chē)隊(duì)很快投入了新賽車(chē)的研發(fā),不幸的是,從工程師那里得到消息,舊車(chē)身的設(shè)計(jì)不能夠裝進(jìn)新研發(fā)的引擎。我們不得不為新的引擎重新打造車(chē)身,于是一輛新的賽車(chē)誕生了。但是,麻煩的事接踵而來(lái),國(guó)際汽聯(lián)頻頻修改規(guī)則,搞得設(shè)計(jì)師在“賽車(chē)”上改了又改,最終變得不成樣子,只能把它廢棄。
為了能夠重用這輛昂貴的賽車(chē),工程師們提出了解決方案:首先,在車(chē)身的設(shè)計(jì)上預(yù)留出安裝引擎的位置和管線。然后,根據(jù)這些設(shè)計(jì)好的規(guī)范設(shè)計(jì)引擎(或是引擎的適配器)。于是,新的賽車(chē)設(shè)計(jì)方案就這樣誕生了。
顯然,通過(guò)重構(gòu),這里應(yīng)用的是一個(gè)典型的Bridge模式。這個(gè)實(shí)現(xiàn)的關(guān)鍵之處在于我們預(yù)先給引擎留出了位置!我們不必因?yàn)閷?duì)引擎的規(guī)則的頻頻變更而制造相當(dāng)多的車(chē)身,而是盡可能地沿用和改良現(xiàn)有的車(chē)身。
說(shuō)到這里,想說(shuō)一說(shuō)OO設(shè)計(jì)的一個(gè)誤區(qū)。
學(xué)習(xí)OO語(yǔ)言的時(shí)候,為了能夠說(shuō)明“繼承”(或者說(shuō)“is-a”)這個(gè)概念,教科書(shū)上經(jīng)常用實(shí)際生活中的例子來(lái)解釋。比如汽車(chē)是車(chē),電車(chē)是車(chē),F(xiàn)1賽車(chē)是汽車(chē),所以車(chē)是汽車(chē)、電車(chē)、F1賽車(chē)的上層抽象。這個(gè)例子并沒(méi)有錯(cuò)。問(wèn)題是,這樣的例子過(guò)于“形象”了!如果OO設(shè)計(jì)直接就可以將現(xiàn)實(shí)生活中的概念引用過(guò)來(lái),那也就不需要什么軟件工程師了!OO設(shè)計(jì)的關(guān)鍵概念是抽象。如果沒(méi)有抽象,那所有的軟件工程師的努力都是徒勞的。因?yàn)槿绻麤](méi)有抽象,我們只能去構(gòu)造世界中每一個(gè)對(duì)象。上面這個(gè)例子中,我們應(yīng)該看到“引擎”這個(gè)抽象的存在,因?yàn)檐?chē)隊(duì)的工程師們?yōu)樗A(yù)留了位置,為它制定了設(shè)計(jì)規(guī)范。
上面這個(gè)設(shè)計(jì)也實(shí)現(xiàn)了后面要說(shuō)的DIP(依賴倒置原則)。但是請(qǐng)記住,OCP是OO設(shè)計(jì)原則中高層次的原則,其余的原則對(duì)OCP提供了不同程度的支持。為了實(shí)現(xiàn)OCP,我們會(huì)自覺(jué)或者不自覺(jué)地用到其它原則或是諸如Bridge、Decorator等設(shè)計(jì)模式。然而,對(duì)于一個(gè)應(yīng)用系統(tǒng)而言,實(shí)現(xiàn)OCP并不是設(shè)計(jì)目的,我們所希望的只是一個(gè)穩(wěn)定的架構(gòu)。所以對(duì)OCP的追求也應(yīng)該適可而止,不要陷入過(guò)渡設(shè)計(jì)。正如Martin本人所說(shuō):“No significant program can be 100% closed.”“Closure not complete but strategic”
(下一篇就要講LSP了,我覺(jué)得這是意義最為重要的OO設(shè)計(jì)原則,它直指當(dāng)今主流OO語(yǔ)言的軟肋,點(diǎn)出了OO設(shè)計(jì)的精髓。)
posted on 2006-01-18 00:26 GHawk 閱讀(7577) 評(píng)論(7) 編輯 收藏 所屬分類: 軟件過(guò)程 、學(xué)習(xí)筆記