日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

(原創(chuàng))一個(gè)優(yōu)秀軟件開(kāi)發(fā)人員的必修課:GRASP

系統(tǒng) 1890 0

我偶然在google或yahoo這樣的搜索引擎搜索GRASP發(fā)現(xiàn),除了國(guó)外的網(wǎng)站,國(guó)內(nèi)網(wǎng)站多介紹和討論GoF而很少介紹GRASP,即使這少量的文章也講解非常粗略。個(gè)人認(rèn)為作為優(yōu)秀的開(kāi)發(fā)人員,理解GRASP比GoF更重要,故寫(xiě)此文章。前面我在 原創(chuàng))一個(gè)優(yōu)秀軟件開(kāi)發(fā)人員的必修課: GRASP 軟件開(kāi)發(fā)模式淺析 中介紹了使用GRASP的目的,今天允許我調(diào)換一下順序,先從低耦合講起,因?yàn)橹T如創(chuàng)建者模式、信息專家模式的根本目的就是降低耦合。

1. 低耦合( Low Coupling

“低耦合”這個(gè)詞相信大家已經(jīng)耳熟能詳,我們?cè)诳? spring 的書(shū)籍、 MVC 的數(shù)據(jù)、設(shè)計(jì)模式的書(shū)籍,無(wú)處不提到“低耦合、高內(nèi)聚”,它已經(jīng)成為軟件設(shè)計(jì)質(zhì)量的標(biāo)準(zhǔn)之一。那么什么是低耦合?耦合就是對(duì)某元素與其它元素之間的連接、感知和依賴的量度。這里所說(shuō)的元素,即可以是功能、對(duì)象(類),也可以指系統(tǒng)、子系統(tǒng)、模塊。假如一個(gè)元素 A 去連接元素 B ,或者通過(guò)自己的方法可以感知 B ,或者當(dāng) B 不存在的時(shí)候就不能正常工作,那么就說(shuō)元素 A 與元素 B 耦合。耦合帶來(lái)的問(wèn)題是,當(dāng)元素 B 發(fā)生變更或不存在時(shí),都將影響元素 A 的正常工作,影響系統(tǒng)的可維護(hù)性和易變更性。同時(shí)元素 A 只能工作于元素 B 存在的環(huán)境中,這也降低了元素 A 的可復(fù)用性。正因?yàn)轳詈系姆N種弊端,我們?cè)谲浖O(shè)計(jì)的時(shí)候努力追求“低耦合”。低耦合就是要求在我們的軟件系統(tǒng)中,某元素不要過(guò)度依賴于其它元素。請(qǐng)注意這里的“過(guò)度”二字。系統(tǒng)中低耦合不能過(guò)度,比如說(shuō)我們?cè)O(shè)計(jì)一個(gè)類可以不與 JDK 耦合,這可能嗎?除非你不是設(shè)計(jì)的 Java 程序。再比如我設(shè)計(jì)了一個(gè)類,它不與我的系統(tǒng)中的任何類發(fā)生耦合。如果有這樣一個(gè)類,那么它必然是低內(nèi)聚(關(guān)于內(nèi)聚的問(wèn)題我隨后討論)。耦合與內(nèi)聚常常是一個(gè)矛盾的兩個(gè)方面。最佳的方案就是尋找一個(gè)合適的中間點(diǎn)。

哪些是耦合呢?

1 .元素 B 是元素 A 的屬性,或者元素 A 引用了元素 B 的實(shí)例(這包括元素 A 調(diào)用的某個(gè)方法,其參數(shù)中包含元素 B )。

2 .元素 A 調(diào)用了元素 B 的方法。

3 .元素 A 直接或間接成為元素 B 的子類。

4 .元素 A 是接口 B 的實(shí)現(xiàn)。

幸運(yùn)的是,目前已經(jīng)有大量的框架幫助我們降低我們系統(tǒng)的耦合度。比如,使用 struts 我們可以應(yīng)用 MVC 模型,使頁(yè)面展現(xiàn)與業(yè)務(wù)邏輯分離,做到了頁(yè)面展現(xiàn)與業(yè)務(wù)邏輯的低耦合。當(dāng)我們的頁(yè)面展現(xiàn)需要變更時(shí),我們只需要修改我們的頁(yè)面,而不影響我們的業(yè)務(wù)邏輯;同樣,我們的業(yè)務(wù)邏輯需要變更的時(shí)候,我們只需要修改我們的 java 程序,與我們的頁(yè)面無(wú)關(guān)。使用 spring 我們運(yùn)用 IoC (反向控制),降低了業(yè)務(wù)邏輯中各個(gè)類的相互依賴。假如類 A 因?yàn)樾枰δ? F 而調(diào)用類 B ,在通常的情況下類 A 需要引用類 B ,因而類 A 就依賴于類 B 了,也就是說(shuō)當(dāng)類 B 不存在的時(shí)候類 A 就無(wú)法使用了。使用了 IoC ,類 A 調(diào)用的僅僅是實(shí)現(xiàn)了功能 F 的接口的某個(gè)類,這個(gè)類可能是類 B ,也可能是另一個(gè)類 C ,由 spring 的配置文件來(lái)決定。這樣,類 A 就不再依賴于類 B 了,耦合度降低,重用性提高了。使用 hibernate 則是使我們的業(yè)務(wù)邏輯與數(shù)據(jù)持久化分離,也就是與將數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)的操作分離。我們?cè)跇I(yè)務(wù)邏輯中只需要將數(shù)據(jù)放到值對(duì)象中,然后交給 hibernate ,或者從 hibernate 那里得到值對(duì)象。至于用 Oracle MySQL 還是 SQL Server ,如何執(zhí)行的操作,與我無(wú)關(guān)。

但是,作為優(yōu)秀的開(kāi)發(fā)人員,僅僅依靠框架提供的降低軟件耦合的方法是遠(yuǎn)遠(yuǎn)不夠的。根據(jù)我的經(jīng)驗(yàn),以下一些問(wèn)題我們應(yīng)當(dāng)引起注意:

1) 根據(jù)可能的變化設(shè)計(jì)軟件

我們采用職責(zé)驅(qū)動(dòng)設(shè)計(jì),設(shè)計(jì)中盡力做到“低耦合、高內(nèi)聚”的一個(gè)非常重要的前提是,我們的軟件是在不斷變化的。如果沒(méi)有變化我們當(dāng)然就不用這么費(fèi)勁了;但是如果有變化,我們希望通過(guò)以上的設(shè)計(jì),使我們?cè)谶m應(yīng)或者更改這樣的變化的時(shí)候,付出更小的代價(jià)。這里提供了一個(gè)非常重要的信息是,我們努力降低耦合的是那些可能發(fā)生變更的地方,因?yàn)榻档婉詈鲜怯写鷥r(jià)的,是以增加資源耗費(fèi)和代碼復(fù)雜度為代價(jià)的。如果系統(tǒng)中某些元素不太可能變更,或者降低耦合所付出的代價(jià)太大,我們當(dāng)然就應(yīng)當(dāng)選擇耦合。有一次我試圖將我的表現(xiàn)層不依賴于 struts ,但發(fā)現(xiàn)這樣的嘗試代價(jià)太大而失去意義了。對(duì)于軟件可能變更的部分,我們應(yīng)當(dāng)努力去降低耦合,這就給我們提出一個(gè)要求是,在軟件設(shè)計(jì)的時(shí)候可以預(yù)判日后的變化。根據(jù)以往的經(jīng)驗(yàn)我認(rèn)為,一個(gè)軟件的業(yè)務(wù)邏輯和采用的技術(shù)框架往往是容易變化的 2 個(gè)方面。客戶需求變更是我們軟件設(shè)計(jì)必須考慮的問(wèn)題。在 RUP 的開(kāi)發(fā)過(guò)程中,為什么需要將分析設(shè)計(jì)的過(guò)程分為分析模型和設(shè)計(jì)模型,愚以為,從分析模型到設(shè)計(jì)模型的過(guò)程實(shí)際上是系統(tǒng)從滿足直接的客戶需求到優(yōu)化系統(tǒng)結(jié)構(gòu)、適應(yīng)可預(yù)見(jiàn)的客戶需求變更的一個(gè)過(guò)程。這種客戶需求的變更不僅僅指對(duì)一個(gè)客戶需求的變更,更是指我們的軟件從適應(yīng)一個(gè)客戶需求到適應(yīng)更多客戶需求的過(guò)程。另一個(gè)方面,現(xiàn)在技術(shù)變更之快, EJB hibernate spring ajax ,一個(gè)一個(gè)的技術(shù)像走馬燈一樣從我們腦海中滑過(guò),我們真不知道明天我在用什么。在這樣的情況下,適應(yīng)變化就是我們最佳的選擇。

2) 合理的職責(zé)劃分

合理的職責(zé)劃分,讓系統(tǒng)中的對(duì)象各司其職,不僅是提高內(nèi)聚的要求,同時(shí)也可以有效地降低耦合。比如評(píng)審計(jì)劃 BUS 、評(píng)審表 BUS 、評(píng)審報(bào)告 BUS 都需要通過(guò)評(píng)審計(jì)劃 DAO 去查詢一些評(píng)審計(jì)劃的數(shù)據(jù),如果它們都去直接調(diào)用評(píng)審計(jì)劃 DAO (如圖 A ),則評(píng)審計(jì)劃 BUS 、評(píng)審表 BUS 、評(píng)審報(bào)告 BUS 三個(gè)對(duì)象都與評(píng)審計(jì)劃 DAO 耦合,評(píng)審計(jì)劃 DAO 一旦變更將與這三個(gè)對(duì)象都有關(guān)。在這個(gè)實(shí)例中,實(shí)際上評(píng)審計(jì)劃 BUS 是信息專家(關(guān)于信息專家模式我將在后面討論),評(píng)審表 BUS 和評(píng)審報(bào)告 BUS 如果需要獲得評(píng)審計(jì)劃的數(shù)據(jù),應(yīng)當(dāng)向評(píng)審計(jì)劃 BUS 提出需求,由評(píng)審計(jì)劃 BUS 提供數(shù)據(jù)(如圖 B )。經(jīng)過(guò)這樣的調(diào)整,系統(tǒng)的耦合度就降低了。

3) 使用接口而不是繼承

通過(guò)對(duì)耦合的分析,我們不難發(fā)現(xiàn),繼承就是一種耦合。如果子類 A 繼承了父類 B ,不論是直接或間接的繼承,子類 A 都必將依賴父類 B 。子類 A 必須使用在存在父類 B 的環(huán)境中,父類 B 不存在子類 A 就不能使用,這樣將影響子類 A 的可移植性。一旦父類 B 發(fā)生任何變更,更改或去掉一個(gè)函數(shù)名,或者改變一個(gè)函數(shù)的參數(shù),都將導(dǎo)致子類 A 不得不變更,甚至重寫(xiě)。假如父類 B 的子類數(shù)十上百個(gè),甚至貫穿這個(gè)項(xiàng)目各個(gè)模塊,這樣的變更是災(zāi)難性的。這種情況最典型的例子是我們現(xiàn)在使用 hibernate spring 設(shè)計(jì) DAO 對(duì)象的方式,具體的描述參見(jiàn)我寫(xiě)的 《如何在 struts + spring + hibernate 的框架下構(gòu)建低耦合高內(nèi)聚的軟件結(jié)構(gòu)》 一文。

總之,“低耦合”給軟件項(xiàng)目帶來(lái)的優(yōu)點(diǎn)是:易于變更、易于重用。

(原創(chuàng))一個(gè)優(yōu)秀軟件開(kāi)發(fā)人員的必修課:GRASP(2)低耦合


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 滁州市| 德州市| 宜章县| 芮城县| 永州市| 高雄县| 正阳县| 鹿邑县| 肇东市| 河西区| 阳西县| 茌平县| 梁山县| 敦化市| 盘山县| 宁蒗| 江油市| 仲巴县| 仁化县| 伊春市| 鹤山市| 喜德县| 曲麻莱县| 开化县| 化隆| 滦平县| 牙克石市| 遂昌县| 炉霍县| 吉木乃县| 南城县| 娄底市| 汉源县| 永川市| 赤峰市| 苗栗市| 海原县| 灵山县| 莲花县| 合山市| 北辰区|