亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? 最大化java代碼的可重用性 (轉(zhuǎn)).txt

?? 《Java技術(shù)大合集》,電子書籍都是從網(wǎng)絡(luò)上搜集整理成TXT文本文件。收集了:Java Socket編程、JSP語法、WebSphere快速入門等。
?? TXT
字號:
作者:jeru
email: jeru@163.net
日期:8/6/2001 5:35:46 PM
最大化JAVA代碼的可重用性

——克服傳統(tǒng)OO方法在重用方面的缺陷

出處: http://www.javaworld.com 
mashy    翻譯  


 

摘要:不要放棄編寫可重用代碼的努力!本文介紹了三種對現(xiàn)有代碼進(jìn)行修改以提高其可重用性的方法。

在程序員中似乎存在著一種日益普遍的觀點(diǎn),認(rèn)為重用只是一個(gè)神話。或許是傳統(tǒng)的面向?qū)ο缶幊谭椒ㄖ兴嬖诘牟蛔阍黾恿酥赜玫睦щy。本文介紹了從另外一種不同的途徑使重用成為可能的三個(gè)步驟。

第一步:將功能實(shí)現(xiàn)從類實(shí)例的方法中移出

由于缺乏精確性,類繼承不是非常理想的代碼重用機(jī)制。換句話說,如果不繼承一個(gè)類的數(shù)據(jù)成員和其他的方法,那么你就無法重用這個(gè)類的某個(gè)單獨(dú)的方法。這些額外的不必要的負(fù)擔(dān)使方法重用的代碼變得復(fù)雜。派生類對其父類的依賴性也以入了額外的復(fù)雜性:對父類的改動(dòng)會(huì)對子類造成影響;當(dāng)修改任意一個(gè)類的時(shí)候,我們很難記得清哪個(gè)方法被覆蓋,哪個(gè)沒有;而且被覆蓋的方法是否會(huì)調(diào)用父類中相應(yīng)的方法并不非常清晰地顯現(xiàn)。

任何執(zhí)行單一概念任務(wù)的方法應(yīng)該能夠成為代碼用的首選而獨(dú)立存在。為了達(dá)到這個(gè)目標(biāo),我們必須會(huì)到過程化的編程模式,將代碼從類實(shí)例的方法中移出,形成具有全局可見性的過程。為了提高這種過程的可重用性,過程代碼應(yīng)該象靜態(tài)的通用方法一樣編寫:每個(gè)過程只能使用自己的輸入?yún)?shù),只能調(diào)用其他全局性的過程完成其工作,不能使用任何非本地的變量。這種對外部依賴的簡化降低了過程使用的復(fù)雜性,也增加了在其他地方使用此過程的可能性。當(dāng)然,由于其結(jié)構(gòu)通常會(huì)變得更為清晰,即使拋開重用的目的不談我們也可以從這種代碼的組織方式中受益。

在Java中,方法不能脫離類而單獨(dú)存在。因此,你可以對相關(guān)的過程進(jìn)行組織并使它們成為一個(gè)獨(dú)立的類中的公共靜態(tài)方法。例如,對于如下所示的一個(gè)類:

class Polygon{


public int getPerimeter(){…}

public boolean isConvex(){…}

public Boolean containsPoint(Point p){…}


}

可以將它改寫成下面的形式:

class Polygon { 


public int getPerimeter() { return pPolygon.computePerimeter(this);} 

public boolean isConvex() { return pPolygon.isConvex(this);} 

public boolean containsPoint() { return pPolygon.containsPoint(this, p);} 


} 

在此處,nPolygon應(yīng)該是這個(gè)樣子:

class pPolygon { 

static public int computePerimeter(Polygon polygon) {...} 

static public boolean isConvex(Polygon polygon) {...} 

static public boolean containsPoint(Polygon polygon, Point p) {...} 


從類的名字pPolygon可以看出,該類所封裝的過程主要與Polygon類型的對象有關(guān)。名字前面的p表示該類的唯一目的是組織公共靜態(tài)過程。在Java中,類的名字以小寫字母開頭不是一種標(biāo)準(zhǔn)的做法,但象pPloygon這樣的類事實(shí)上并不執(zhí)行普通類的功能。也就是說,它并不代表著一類對象,它只是語言本身所需要的用于代碼組織的實(shí)體。

 在上面這個(gè)例子中,改動(dòng)代碼的總體影響是使得客戶代碼不必為了重用其功能而從Polygon繼承。Polygon類的功能現(xiàn)在已經(jīng)由pPolygon類以過程為單位提供。客戶代碼只使用自己需要的代碼,無需關(guān)心自身并不需要的功能。

這并不意味著在這種新型的過程化編程模式中,類不服務(wù)于更有用的目的。恰恰相反,類執(zhí)行組織和封裝對象數(shù)據(jù)成員的必要工作。而且它們通過多重接口實(shí)現(xiàn)多態(tài)性的能力也為代碼重用提供了顯著的支持,這將在下一個(gè)步驟中討論。然而,由于將功能實(shí)現(xiàn)包含在實(shí)例方法中無法實(shí)現(xiàn)理想的代碼重用,所以通過類繼承實(shí)現(xiàn)代碼重用和多態(tài)性支持也不應(yīng)成為最佳的技術(shù)選擇。

在一本被廣為閱讀的書《Design Patterns》中曾簡要地提及一種略有不同的技術(shù)。策略模式(Strategy Pattern)提倡將相關(guān)算法的每個(gè)成員封裝在一個(gè)通用的接口下,以便于客戶端代碼可交換地使用其算法。由于一個(gè)算法通常被作為一個(gè)或幾個(gè)獨(dú)立的過程進(jìn)行編碼,這種封裝更注重執(zhí)行單獨(dú)任務(wù)的過程的重用,而不是執(zhí)行多種任務(wù)的、包含代碼和數(shù)據(jù)的對象的重用。這一步驟體現(xiàn)了相同的基本思想。

然而,將一個(gè)算法封裝在一個(gè)接口下意味著將算法作為實(shí)現(xiàn)接口的對象進(jìn)行編碼。這意味著我們?nèi)匀灰蕾囉谝粋€(gè)與所包裝的對象的數(shù)據(jù)和其他方法相耦合的過程,這樣便會(huì)使其復(fù)用變得復(fù)雜。此外還存在這樣一個(gè)問題,每次需要使用這個(gè)算法的時(shí)候都必須實(shí)例化這些對象,這便會(huì)降低程序的性能。值得慶幸的是,設(shè)計(jì)模式提供了針對這兩個(gè)問題的解決方法。可以在對策略對象進(jìn)行編碼時(shí)應(yīng)用享元模式(Flyweight Pattern,譯者注:還存在一種譯法為輕量模式),這樣每個(gè)對象只會(huì)存在一個(gè)被共知共享的實(shí)例(這針對程序性能的問題),而且每個(gè)共享對象在訪問間隔中并不維持狀態(tài)(于是對象將沒有數(shù)據(jù)成員,這針對大多數(shù)的耦合問題)。由此產(chǎn)生的享元--策略模式非常類似于在這一步驟中所提到的將功能實(shí)現(xiàn)封裝在全局可見的、無狀態(tài)的過程中的技術(shù)。(譯者注:以上這兩段文字讀起來可能有些晦澀難解,建議有興趣的讀者參閱文中所提到《設(shè)計(jì)模式》一書,Erich Gamma等著、李英軍等譯、機(jī)械工業(yè)出版社出版。)

第二步:將非原始的輸入?yún)?shù)類型改為接口類型

在面向?qū)ο缶幊讨校a重用的真正基礎(chǔ)在于通過接口參數(shù)類型利用多態(tài)性,而不是通過類繼承,正如Allen Holub在 “Build User Interfaces for Object-Oriented System, Part 2”中所述:

“……你應(yīng)該通過對接口而不是類編程實(shí)現(xiàn)重用。如果一個(gè)方法的所有參數(shù)都是某個(gè)已知接口的引用,這個(gè)接口由一些你所不知道的類實(shí)現(xiàn),那么這個(gè)方法就能夠操作這樣一些對象:當(dāng)編寫方法的代碼時(shí),這些對象的類甚至還不存在。從技術(shù)上講,可重用的是方法,而不是傳遞給方法的對象。”

將Holub所講的方法應(yīng)用于第一步所得到的結(jié)果,只要某塊功能代碼能夠作為一個(gè)全局可見的過程而獨(dú)立存在,你就可以將其每個(gè)類類型(class-type)的輸入?yún)?shù)改為一個(gè)接口類型,這樣便能進(jìn)一步提高其重用的潛力。那么,實(shí)現(xiàn)此接口類型的任何類的對象都可以作為參數(shù)使用,而不僅僅局限于原始類。由此,這個(gè)過程對可能存在的大量的對象類型都成為可用的。

例如,有這樣一個(gè)全局可見的靜態(tài)過程

static public boolean contains(Rectangle rect, int x, int y) {…}

這個(gè)方法用于檢查給定的矩形是否包含某個(gè)給定的點(diǎn)。在這個(gè)例子中,rect參數(shù)的類型可以從Rectangle類改變?yōu)榻涌陬愋停缦滤荆?
static public boolean contains(Rectangular rect, int x, int y){…}

Rectangular可以是下面形式的接口:

public interface Rectangular{

       Rectangle getBounds();

}

現(xiàn)在,所有可以被描述為矩形的類(也就意味著實(shí)現(xiàn)了Rectangular接口)的對象都可以作為傳遞給pRectangular.contains()的rect參數(shù)。通過放寬所傳遞的參數(shù)類型的限制,我們使方法具有更好的可重用性。

不過,在上面這個(gè)例子中,Rectangular接口的getBounds方法返回一個(gè)Rectangle類型,你可能會(huì)懷疑使用這個(gè)接口是否具有真正的價(jià)值;換句話說,如果我們知道傳入過程的對象會(huì)在被調(diào)用時(shí)返回一個(gè)Rectangle,為什么不直接傳入Rectangle取代接口類型呢?不這樣做的最重要原因與集合有關(guān),假設(shè)有這樣一個(gè)方法:

static public boolean areAnyOverlapping(Collection rects) {…}

這個(gè)方法的目的在于檢查給定集合中的任意矩形對象是否存在重疊。那么,在方法內(nèi)部遍歷集合中的每個(gè)對象時(shí),如果無法將對象造型(cast)成如Rectangular這樣的接口類型,那么將如何能夠訪問對象的矩形區(qū)域呢?唯一的選擇是將對象造型成為其特定的類型(我們直到它有一個(gè)能夠返回rectangle的方法),這意味著方法必須事先知道其所要操作的是什么類型。這恰恰是這一步驟力圖首先要避免的問題!

第三步:選擇低耦合的輸入?yún)?shù)接口類型

完成第二步之后,應(yīng)該選擇什么樣的接口類型來取代給定的類型呢?答案是能夠通過參數(shù)完全描述過程的需求,同時(shí)又具有最少的額外負(fù)擔(dān)的接口類型。參數(shù)對象所要實(shí)現(xiàn)的接口越簡單,其他特定類實(shí)現(xiàn)此接口的機(jī)會(huì)就越大——由此,其對象可以作為參數(shù)使用的類也就越多。通過下面的例子可以很容易地看到這點(diǎn):

static public boolean areOverlapping(Window window1, Window window2) {...}

這個(gè)方法用于檢查兩個(gè)窗口(假定是矩形窗口)是否重疊,如果這個(gè)方法只要求從參數(shù)獲得兩個(gè)窗口的矩形坐標(biāo),那么簡化參數(shù)的類型使其能反映這個(gè)事實(shí)是一種更好的選擇:

static public boolean areOverlapping(Rectangular rect1, Rectangular rect2) {...}

以上的代碼假設(shè)先前的Window類型的對象同樣可以實(shí)現(xiàn)Rectangular接口。現(xiàn)在對于所有的矩形對象,都可以重用第一個(gè)方法所包含的功能了。

你可能多次體驗(yàn)到當(dāng)一個(gè)接口能夠完全確定需要通過參數(shù)獲哪那些內(nèi)容時(shí),會(huì)存在太多不必要的方法。在這種情況下,應(yīng)該在全局命名空間中定義一個(gè)新的公共接口以供其他可能面臨同一困境的方法重用。

你可能還會(huì)不止一次地發(fā)現(xiàn),在確定需要通過單一過程的一個(gè)參數(shù)獲取哪些內(nèi)容時(shí),最好創(chuàng)建一個(gè)單獨(dú)的接口。你應(yīng)該只為這個(gè)參數(shù)使用此接口。這通常會(huì)在你希望如同C語言中的函數(shù)指針一樣使用參數(shù)的情況下出現(xiàn)。例如下面的過程:

static public void sort(List list, SortComparison comp) {...}

此過程使用參數(shù)所提供的比較對象comp,通過比較給定列表中的所有對象而對其進(jìn)行排序,sort對comp的全部要求是調(diào)用一個(gè)單獨(dú)的方法進(jìn)行比較。因此,SortComparison應(yīng)該是只帶有一個(gè)方法的接口:

public interface SortComparison { 

boolean comesBefore(Object a, Object b); 

} 

這個(gè)接口的唯一目的是為sort提供一個(gè)與其完成任務(wù)所需功能相聯(lián)系的鉤子(hook),因此SortComparison無法在其他地方重用。

結(jié)束語

以上所述的三個(gè)步驟用于現(xiàn)有的、按照相對傳統(tǒng)的面向?qū)ο蠓椒ㄋ帉懙拇a。這些步驟與面向?qū)ο缶幊碳夹g(shù)結(jié)合就形成了一種可以運(yùn)用于今后代碼編寫中的新方法,它可以提高代碼的可重用性和內(nèi)聚性,同時(shí)降低了耦合度及復(fù)雜性。

很顯然,這些步驟無法運(yùn)用于那些在本質(zhì)上就不適合于重用的代碼。這類代碼通常出現(xiàn)在應(yīng)用程序的表示層(presentation layer)。例如程序中用于創(chuàng)建用戶界面的代碼,以及將輸入事件與完成實(shí)際工作的過程相聯(lián)系的控制代碼,都是屬于那種其功能在不同的程序中差別很大的代碼,這種代碼的重用幾乎是不可能的。

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
午夜激情一区二区三区| 色哟哟一区二区| 成人午夜视频福利| 日本韩国一区二区三区视频| 欧美精品在线观看播放| 久久一留热品黄| 亚洲综合自拍偷拍| 国内成人自拍视频| 欧洲视频一区二区| 337p粉嫩大胆噜噜噜噜噜91av | 奇米亚洲午夜久久精品| 国产成人无遮挡在线视频| 欧美午夜精品一区二区蜜桃| 欧美精品一区二区三区四区| 一区二区三区四区不卡视频| 久久91精品久久久久久秒播| 日本高清不卡一区| 久久毛片高清国产| 丝瓜av网站精品一区二区| 成人午夜电影网站| 欧美一级高清大全免费观看| 中文字幕日韩av资源站| 久久国产夜色精品鲁鲁99| 一本久道久久综合中文字幕 | 国产精品资源站在线| 欧美三级一区二区| 欧美激情综合在线| 日本不卡一区二区三区 | 亚洲精品国久久99热| 国产精品自拍av| 在线电影一区二区三区| 中文字幕在线观看一区| 精品一区二区三区视频在线观看| 色视频一区二区| 国产精品理论片| 国内精品第一页| 欧美一区二区三区视频免费| 曰韩精品一区二区| av男人天堂一区| 久久久影院官网| 久久99久久久久| 欧美日韩aaaaaa| 亚洲日本欧美天堂| 国产超碰在线一区| 精品国产一区二区三区久久久蜜月| 亚洲国产成人tv| 97久久超碰国产精品电影| 久久久欧美精品sm网站| 麻豆国产精品官网| 欧美一区二区在线播放| 香蕉加勒比综合久久| 91香蕉视频在线| 亚洲欧洲精品一区二区精品久久久| 国产福利一区二区三区视频| 精品国产乱码久久久久久夜甘婷婷 | 蜜臀国产一区二区三区在线播放| 欧美午夜电影网| 亚洲一区成人在线| 在线观看不卡一区| 一区二区在线观看视频在线观看| 成人av网站在线观看免费| 久久久久国产精品人| 激情六月婷婷久久| 精品国产网站在线观看| 精品一区二区三区视频| 久久久美女艺术照精彩视频福利播放| 麻豆精品视频在线观看| 精品乱人伦一区二区三区| 韩国av一区二区三区四区| www久久久久| 国产91丝袜在线观看| 中文一区一区三区高中清不卡| 国产成人免费视频网站| 欧美韩国日本不卡| aaa欧美色吧激情视频| 亚洲欧洲制服丝袜| 欧美亚洲国产一区在线观看网站| 亚洲综合色丁香婷婷六月图片| 在线观看成人小视频| 亚洲18色成人| 欧美变态tickling挠脚心| 激情小说亚洲一区| 中文子幕无线码一区tr| 91视频一区二区| 亚洲6080在线| 精品久久久久久久久久久院品网| 国产精品91一区二区| 18成人在线视频| 欧美肥胖老妇做爰| 精品亚洲欧美一区| 国产精品成人一区二区艾草| 91色.com| 日本欧美肥老太交大片| 久久精品在线免费观看| 91视频.com| 日本欧美一区二区三区| 国产喷白浆一区二区三区| 91在线精品秘密一区二区| 亚洲国产成人va在线观看天堂| 日韩一区二区视频| 成人午夜激情影院| 亚洲国产成人av好男人在线观看| 欧美成人一区二区三区片免费| 成人激情综合网站| 亚洲小说欧美激情另类| 欧美精品一区二| 日本福利一区二区| 激情综合色丁香一区二区| 亚洲欧美激情插| 欧美一级片免费看| 99精品一区二区三区| 日韩电影在线一区二区三区| 国产三级精品三级在线专区| 91国产视频在线观看| 国产一区二区在线免费观看| 一区二区三区四区在线| 精品国产一区久久| 91久久精品一区二区三| 久久99精品久久久久久动态图| 1024亚洲合集| 欧美成人性战久久| 在线精品视频小说1| 国产精品一级二级三级| 亚洲超丰满肉感bbw| 中文一区二区完整视频在线观看| 欧美老女人第四色| 北条麻妃一区二区三区| 免费观看在线色综合| 亚洲精品少妇30p| 久久精品视频一区二区| 91麻豆精品国产91久久久久| 99久久久国产精品| 国产在线精品一区二区三区不卡| 亚洲精品日日夜夜| 国产清纯美女被跳蛋高潮一区二区久久w | 久久久亚洲精品石原莉奈| 欧美综合久久久| 国产高清成人在线| 免费一级片91| 夜夜亚洲天天久久| 国产精品激情偷乱一区二区∴| 日韩免费观看2025年上映的电影 | 亚洲精品乱码久久久久久久久 | 91麻豆6部合集magnet| 国产精品一区三区| 三级一区在线视频先锋 | 欧美日韩中文字幕一区| 成人中文字幕合集| 久久精品国产亚洲一区二区三区 | 欧美剧情片在线观看| 99精品欧美一区二区蜜桃免费| 精品午夜久久福利影院 | 2017欧美狠狠色| 欧美顶级少妇做爰| 欧美专区日韩专区| 91丝袜呻吟高潮美腿白嫩在线观看| 国产精品亚洲第一区在线暖暖韩国| 三级在线观看一区二区| 亚洲国产日韩一区二区| 中文字幕亚洲在| 国产精品网站在线播放| 久久久综合视频| www久久精品| 精品91自产拍在线观看一区| 日韩一区二区三区在线观看| 欧美色男人天堂| 在线观看一区不卡| 色8久久人人97超碰香蕉987| 一本到不卡精品视频在线观看| 成人av集中营| 成人网在线免费视频| 国产一区二区三区免费看| 国内成人精品2018免费看| 久草热8精品视频在线观看| 免费精品99久久国产综合精品| 日韩精品一区第一页| 午夜欧美视频在线观看| 视频一区视频二区中文| 日本视频中文字幕一区二区三区| 日韩精品福利网| 看电视剧不卡顿的网站| 久久99国产精品久久99果冻传媒| 久久99热国产| 国产福利一区二区| 成人sese在线| 色视频欧美一区二区三区| 欧美中文字幕一区| 欧美酷刑日本凌虐凌虐| 91精品国产手机| 欧美成人精品3d动漫h| 2017欧美狠狠色| 国产精品美女久久久久aⅴ| 成人免费小视频| 亚洲无人区一区| 日韩经典一区二区| 国内欧美视频一区二区| 国产**成人网毛片九色 | 日欧美一区二区| 捆绑变态av一区二区三区| 国产乱理伦片在线观看夜一区|