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

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

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

?? 收集來的一些java方面的技術(shù)
?? TXT
字號(hào):
作者: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è)神話?;蛟S是傳統(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類以過程為單位提供??蛻舸a只使用自己需要的代碼,無需關(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è)問題的解決方法??梢栽趯Σ呗詫ο筮M(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ū)ο缶幊讨?,代碼重用的真正基礎(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接口?,F(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
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲国产视频直播| 国产精品乱人伦| av中文字幕亚洲| 日韩精品一区第一页| 日本一区二区免费在线观看视频| 91国偷自产一区二区开放时间| 激情久久五月天| 一区二区三区四区在线免费观看 | 欧美人伦禁忌dvd放荡欲情| 国产在线不卡一卡二卡三卡四卡| 亚洲蜜臀av乱码久久精品蜜桃| 欧美电影免费观看高清完整版 | 免费成人av在线播放| 中文字幕一区二区在线观看| 日韩午夜小视频| 欧美中文字幕一区| kk眼镜猥琐国模调教系列一区二区| 免费日韩伦理电影| 午夜精品爽啪视频| 亚洲蜜臀av乱码久久精品蜜桃| 国产亚洲欧美日韩日本| 日韩午夜激情免费电影| 欧美精选一区二区| 欧美曰成人黄网| 色婷婷综合激情| 91视视频在线观看入口直接观看www | 色婷婷av一区二区三区gif| 国产露脸91国语对白| 蜜臀av一区二区在线观看| 亚洲成人资源在线| 亚洲综合丝袜美腿| 亚洲麻豆国产自偷在线| 亚洲欧美日韩精品久久久久| 国产精品国产三级国产普通话蜜臀| 久久久久久久久岛国免费| 欧美va亚洲va| 日韩欧美一区中文| 欧美一级理论性理论a| 制服.丝袜.亚洲.中文.综合| 欧美日韩一区二区不卡| 欧美日韩免费高清一区色橹橹 | 99国内精品久久| 99精品久久免费看蜜臀剧情介绍| 国产成人精品一区二区三区四区| 国产乱人伦偷精品视频免下载| 国精品**一区二区三区在线蜜桃 | 色综合视频在线观看| 北条麻妃国产九九精品视频| 成人av在线电影| 91麻豆视频网站| 在线精品视频小说1| 欧美天天综合网| 欧美日韩高清一区| 欧美岛国在线观看| 337p日本欧洲亚洲大胆精品| 久久影院电视剧免费观看| 久久精品视频在线看| 国产精品免费久久| 亚洲男人的天堂一区二区| 亚洲一区欧美一区| 日韩电影在线一区二区三区| 久久精品国产秦先生| 国产美女在线精品| 99精品国产99久久久久久白柏 | 91久久一区二区| 欧美日韩亚洲另类| 26uuu国产在线精品一区二区| 国产偷v国产偷v亚洲高清| 最新欧美精品一区二区三区| 亚洲在线视频一区| 久久99精品国产.久久久久久| 国产精品一区二区x88av| 99r国产精品| 69精品人人人人| 国产精品系列在线| 亚洲第四色夜色| 国产盗摄女厕一区二区三区| 91麻豆成人久久精品二区三区| 欧美日韩国产美女| 国产欧美一区在线| 亚洲成人av免费| 国产一区二区在线电影| 91在线精品一区二区三区| 91麻豆精品国产91久久久资源速度 | 国产麻豆91精品| 色老汉一区二区三区| 亚洲精品在线观看网站| 亚洲青青青在线视频| 麻豆精品视频在线| 色婷婷国产精品综合在线观看| 精品伦理精品一区| 一区二区三区在线观看网站| 精品亚洲porn| 在线免费一区三区| 久久久久久免费网| 图片区日韩欧美亚洲| 国产·精品毛片| 欧美一区2区视频在线观看| 成人免费在线观看入口| 乱一区二区av| 欧美亚洲一区二区在线| 国产精品你懂的| 九九**精品视频免费播放| 色哟哟一区二区三区| 久久久精品人体av艺术| 日精品一区二区| 91激情在线视频| 中文字幕不卡在线| 精品一区免费av| 欧美日韩国产美| 一二三区精品视频| 成人精品小蝌蚪| 久久久精品2019中文字幕之3| 五月天视频一区| 97成人超碰视| 欧美极品少妇xxxxⅹ高跟鞋| 久久99这里只有精品| 欧美福利视频一区| 一区二区理论电影在线观看| 97超碰欧美中文字幕| 国产精品视频看| 国产一区二区毛片| 精品日本一线二线三线不卡| 婷婷综合在线观看| 欧美日韩精品一区二区天天拍小说 | 国产日产欧美一区| 精品在线一区二区| 精品国精品国产尤物美女| 免费成人你懂的| 欧美一级日韩免费不卡| 日韩av一二三| 欧美日韩高清一区| 天堂久久一区二区三区| 欧美精品v日韩精品v韩国精品v| 一区二区三区四区在线播放| 色8久久人人97超碰香蕉987| 最新久久zyz资源站| 色综合天天天天做夜夜夜夜做| 亚洲欧洲日韩av| 91色九色蝌蚪| 亚洲人xxxx| 欧美色偷偷大香| 亚洲成av人片在线| 91精品国产一区二区| 久久精品国产亚洲5555| 久久久精品黄色| 99精品久久只有精品| 亚洲精品亚洲人成人网| 欧美理论片在线| 美女精品一区二区| 久久精品人人做人人爽人人| 成人毛片在线观看| 一区二区三区在线观看网站| 欧美日韩国产综合久久| 麻豆精品一区二区三区| 久久久久久久久一| 91丨九色porny丨蝌蚪| 亚洲一区二区三区爽爽爽爽爽| 欧美日韩免费视频| 国内精品国产三级国产a久久| 欧美极品少妇xxxxⅹ高跟鞋| 色噜噜狠狠成人中文综合 | 午夜久久电影网| 日韩精品一区二区三区四区视频| 国产成人午夜99999| 国产精品拍天天在线| 欧美撒尿777hd撒尿| 精品一区二区久久| 中文字幕在线观看不卡视频| 欧美艳星brazzers| 久久国产精品区| 国产精品久久久久久久久果冻传媒| 色婷婷亚洲婷婷| 麻豆国产欧美日韩综合精品二区| 久久久99免费| 欧洲中文字幕精品| 激情综合网激情| 亚洲免费观看视频| 欧美zozo另类异族| 色拍拍在线精品视频8848| 久久99国产精品免费| 亚洲日本在线a| 日韩女优毛片在线| 色综合久久综合中文综合网| 精品一区二区综合| 亚洲乱码中文字幕| 久久影院午夜片一区| 欧美性猛交xxxx乱大交退制版| 久久精品国产免费| 亚洲一区欧美一区| 国产精品欧美经典| 欧美一区二区成人| 在线精品视频一区二区三四 | 成人在线视频首页| 日韩精品亚洲一区二区三区免费| 国产欧美日韩不卡免费| 欧美老女人第四色| 91福利视频网站| 国产a级毛片一区| 视频在线在亚洲|