?
快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

www9778con:提高Java代碼可重用性的三個措施

?

作者:松下客

本文先容了三種改動現有代碼前進其可重用性的措施,它們分手是:改寫類的實例措施,把參數類型改成接口,選擇最簡單的參數接口類型。

步伐一:改寫類的實例措施

經由過程類承襲實今世碼重用不是正確的代碼重用技巧,是以它并不是最抱負的代碼重用機制。換句話說,假如不承襲全部類的所有措施和數據成員,我們無法重用該類里面的單個措施。承襲老是帶來一些多余的措施和數據成員,它們老是使得重用類里面某個措施的代碼繁雜化。別的,派生類對父類的依附關系也使得www9778con代碼進一步繁雜化:對父類的篡改可能影響子類;改動父類或者子類中的隨意率性一個類時,我們很難記得哪一個措施被子類覆蓋、哪一個措施沒有被子類覆蓋;著末,子類中的覆蓋措施是否要調用父類中的對應措施無意偶爾并不顯而易見。

任何措施,只要它履行的是某個單一觀點的義務,就其本身而言,它就應該是首選的可重用代碼。為了重用這種代碼,我們必須回歸到面向歷程的編程模式,把類的實例措施移出成為全局性的歷程。為了前進這種歷程的可重用性,歷程代碼應該象靜態對象措施一樣編寫:它只能應用自己的輸入參數,只能調用其他全局性的歷程,不能應用任何非局部的變量。這種對外部依附關系的限定簡化了歷程的利用,使得歷程能夠方便地用于任何地方。當然,因為這種組織要領老是使得代碼具有更清晰的布局,縱然是不斟酌重用性的代碼也同樣能夠從中獲益。

在Java中,措施不能離開類而零丁存在。為此,我們可以把相關的歷程組織成為自力的類,并把這些歷程定義為公用靜態措施。

例如,對付下面這個類:

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(Point p) {return pPolygon.containsPoint(this, p);}

.

}

此中,pPolygon是:

class pPolygon {

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

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

static public boolean

containsPoint(Polygon polygon, Point p) {...}

}

從類的名字pPolygon可以看出,該類所封裝的歷程主要與Polygon類型的工具有關。名字前面的p表示該類的獨一目的是組織公用靜態歷程。在Java中,類的名字以小寫字母開首是一種非標準的做法,但象pPloygon這樣的類事實上并不供給通俗Java類的功能。也便是說,它并不代表著一類工具,它只是Java說話組織代碼的一種機制。

在上面這個例子中,篡改代碼的終極效果是使得利用Polygon功能的客戶代碼不必再從Polygon承襲。Polygon類的功能現在已經過pPolygon類以歷程為單位供給??蛻舸a只應用自己必要的代碼,無需關心Polwww9778conygon類中自己不必要的功能。但它并不料味著在這種新式歷程化編程中類的感化有所削弱。恰好相反,在組織和封裝工具數據成員的歷程中,類起到了弗成或缺的感化,而且正如本文接下來所先容的,類經由過程多重接口實現多態性的能力本身也帶來了卓越的代碼重用支持。然而,因為用實例措施封裝代碼功能并不是首選的代碼重用手段,以是經由過程類承襲達到代碼重用和多態性支持也不是最抱負的。

步伐二:把參數類型改成接口

正如Allen Holub在《Build User Interfaces for Object-Oriented Systems》中所指出的,在面向工具編程中,代碼重用真正的要點在于經由過程接口參數類型使用多態性,而不是經由過程類承襲:

“……我們經由過程對接口而不是對類編程達到代碼重用的目的。假如某個措施的所有參數都是對一些已知接口的引用,那么這個措施就能夠操作這樣一些工具:當我們編寫措施的代碼時,這些工具的類以致還不存在。從技巧上說,可重用的是措施,而不是通報給措施的工具?!?/p>

在“步伐一”獲得的結果上利用Holub的見地,當某塊代碼能夠編寫為自力的全局歷程時,只要把它所有類形式的參數改為接口形式,我們就可以進一步前進它的可重用能力。顛末這個篡改之后,歷程的參數可所以實現了該接口的所有類的工具,而不僅僅是原本的類所創建的工具。由此,歷程將能www9778con夠對可能存在的大年夜量的工具類型進行操作。

例如,假設有這樣一個全局靜態措施:

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

這個措施用于反省指定的點是否包孕在矩形里面。在這個例子中,rect參數的類型可以從Rectangle類改變為接口類型,如下所示:

static publiwww9778conc boolean contains(Rectangular rect, int x, int y) {...}

而Rectangular接口的定義是:

public interface Rectangular {Rectangle getBounds();}

現在,所有可以描述為矩形的類(即,實現了Rectangular接口的類)所創建的工具都可以作為供給給pRectangular.contains()的rect參數。經由過程放寬參數類型的限定,我們使措施具有更好的可重用性。

不過,對付上面這個例子,Rectangular接口的getBounds措施返回Rectangle,你可能會狐疑這么做是否真正值得。換言之,假如我們知道傳入歷程的工具會在被調用時返回一個Rectangle,為什么不直接傳入Rectangle取代接口類型呢?之以是不這么做,最緊張的緣故原由與聚攏有關。讓我們假設有這樣一個措施:

static public boolean areAnyOverlapping(Collection rects) {...}

該措施用于反省給定聚攏中的隨意率性矩形工具是否重疊。在這個措施的內部,當我們用輪回依次造訪聚攏中的各個工具時,假如我們不能把工具cast成為Rectangular之類的接口類型,又若何能夠造訪工具的矩形區域呢?獨一的選擇是把工具cast成為它特有的類形式(我們知道它有一個措施可以返回矩形),它意味著措施必須事先知道它所操作的工www9778con具類型,從而使得措施的重用只限于那幾種工具類型。而這恰是前面這個步伐力求先行避免的問題!

步伐三:選擇最簡單的參數接口類型

在實施第二個步伐時,應該選用哪一種接口類型來取代給定的類形式?謎底是哪一個接口完全滿意歷程對參數的需求,同時又具有起碼的多余代碼和數據。描述參數工具要求的接口越簡單,其他類實現該接口的時機就越大年夜??由此,其工具能夠作為參數應用的類也越多。從下面這個例子可以很輕易地看出這一點:

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

這個措施用于反省兩個窗口(假定是矩形窗口)是否重疊。假如這個措施只要求從參數得到兩個窗口的矩形坐標,此時響應地簡化這兩個參數是一種更好的選擇:

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

上面的代碼假定Window類型實現了Rectangular接口。顛末篡改之后,對付任何矩形工具我們都可以重用該措施的功能。

有些時刻可能會呈現描述參數需求的接口擁有太多措施的環境。此時,我們應該在全局名稱空間中定義一個新的公共接口供其他面臨同一問題的代碼重用。

當我們必要象應用C說話中的函數指針一樣應用參數時,創建獨一的接口描述參數需求是最好的選擇。例如,假設有下面這個歷程:

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

該措施運用參數中供給的對照工具comp,經由過程對照給定列表list中的工具排序list列表。sort對comp工具的獨一要求是要調用一個措施進行對照。是以,SortComparison應該是只帶有一個措施的接口:

public interface SortComparison {

boolean comesBefore(Object a, Object b);

}

SortComparison接口的獨一目的在于為sort供給一個它所需功能的鉤子,是以SortComparison接口不能在其他地方重用。

總而言之,本文三個步伐得當于改造現有的、按照面向工具常規編寫的代碼。這三個步伐與面向工具編程技巧結合就獲得了一種可在今后編寫代碼時應用的新式代碼編寫技巧,它能夠簡化措施的繁雜性和依附關系,同時前進措施的可重用能力和內部凝聚力。

當然,這里的三個步伐不能用于那些生造詣不得當重用的代碼。不得當重用的代碼平日呈現在利用的體現層。例如,創建法度榜樣用戶界面的代碼,以及聯絡到輸入事故的節制代碼,都屬于那種在法度榜樣和法度榜樣之間千差萬其余代碼,這種代碼險些弗成能重用。

免責聲明:以上內容源自網絡,版權歸原作者所有,如有侵犯您的原創版權請告知,我們將盡快刪除相關內容。

您可能還會對下面的文章感興趣:

快三平台开户