喜歡這樣的網(wǎng)嗎?雖然,東西比較多,但是,還是蠻清晰的。無論你喜歡與否,這確實(shí)是個好東西,出自于SUN公司的牛人之作。它是JDK里的集合部分。當(dāng)然,這樣的東西,只能算是utilClass,如果你不想用,完全可以自己造幾個輪子,反正,我是不會去造的,除非滿足不了需求。
這個類層次基本是基于接口的。從頂層到下層,上層都是以抽象呈現(xiàn)的。然后,下層是具體的實(shí)現(xiàn)類。這沒啥好說的,但是,關(guān)鍵是,如果讓你設(shè)計這個的一個集合類層次。你會怎么設(shè)計呢?當(dāng)然,跑得起來的代碼也叫設(shè)計,這里就存在好的設(shè)計與糟糕的設(shè)計之分了。所以,設(shè)計時要考慮很多因素,比如可擴(kuò)展性啦,可維護(hù)性啦,面向抽象編程啦,SRP,OCP等幾個面向?qū)ο笤O(shè)計原則啦,反正就是很多,大大小小的綜合因素權(quán)衡出一個設(shè)計結(jié)果。還有,千萬不要小看對于這樣的類層次的深刻理解,它對于你的面向?qū)ο笏枷胗兄鴺O大的幫助。某某天,你參與了一個項目,首先得會做設(shè)計哦,并且,得設(shè)計好,不然,架構(gòu)師就空有其名了。 當(dāng)我在思考這個主題時,我產(chǎn)生了不少想法。有些可能是不成熟的。還是列出來下。
1. 自上而下設(shè)計
2. 自下而上設(shè)計
3. 基于接口的多個行為有異的類繼承設(shè)計
1 . 自上而下設(shè)計
概念很明確,就是從接口抽象類開始。但是,你必須對于幾個具體實(shí)現(xiàn)的抽象部分有著清晰的認(rèn)識。并且你大致了解了這些具體實(shí)現(xiàn)類的規(guī)模以及職責(zé)所在,否則就變成了異形。然而,設(shè)計本身是個跌代的過程,所以,這是個不錯的選擇方案。
2。自下而上設(shè)計
你不了解具體實(shí)現(xiàn)類的規(guī)模以及職責(zé)所在,你只是隨意或者僅僅針對于某一需求,寫了一個輔助類。當(dāng)然,你知道這個類是個有狀態(tài)類,同時,它似乎在某個時刻跟別人有著某某關(guān)系(不知道是繼承還是委托),所以,你沒把這個類設(shè)計成為abstract, final, private constrcutor,OK,你只是保留著這種變化。然后,你又寫了一個類,然后,發(fā)現(xiàn)這兩個類有著共同的部分。然后,又寫了一個,發(fā)現(xiàn)了不少新的東西。恩,很好,需要動作了,你開始思考怎么用設(shè)計模式把這些共同部分(可能在不同類有不同的實(shí)現(xiàn))組織起來。對于,抽象方法,template模式能幫你解決大部分問題。同時,你需要到委托,所以,你還得考慮怎么使用委托才能得到良好的設(shè)計----可參考設(shè)計模式之進(jìn)化論。
3。基于接口的多個行為有異的類繼承設(shè)計
無論采用哪一種方式做設(shè)計。都能得到最終的好結(jié)果。而結(jié)果也基本是一致的。
下面是個例子。
你寫了一個接口,并且提供了兩實(shí)現(xiàn)類。
interface MyInterface{
public void println();
public void print();
public int size();
public boolean isEmpty();
}
class MyConcreteClassA implements MyInterface{
public boolean isEmpty() {
return size() == 0;
}
public void print() {
System.out.print("A");
}
public void println() {
System.out.println("A");
}
public int size() {
return 0;
}
}
class MyConcreteClassB implements MyInterface{
public boolean isEmpty() {
return size() == 0;
}
public void print() {
System.out.print("B");
}
public void println() {
System.out.println("B");
}
public int size() {
return 0;
}
}
然而,你又發(fā)現(xiàn)這兩個實(shí)現(xiàn)類中有著共同的東西--isEmpty方法。所以,你得提取出來,頂層是個接口,沒法放實(shí)現(xiàn)體。放哪里呢?有一個好的辦法,就是把接口改成抽象類。記住,接口的條件比抽象類更強(qiáng)。改造如下:

abstract class MyAbstractClass{
public abstract void println();
public abstract void print();
public abstract int size();
public boolean isEmpty(){
return size() == 0;
}
}
class MyConcreteClassA extends MyAbstractClass{
public void print() {
System.out.print("A");
}
public void println() {
System.out.println("A");
}
public int size() {
return 0;
}
}
class MyConcreteClassB extends MyAbstractClass{
public void print() {
System.out.print("B");
}
public void println() {
System.out.println("B");
}
public int size() {
return 0;
}
}
這個template模式幫你解決了問題。同時,你也能保持住基于抽象編程這個好東西。
那么,還有一種方案,也就是JDK設(shè)計所使用的。

interface MyInterface{
public void println();
public void print();
public int size();
public boolean isEmpty();
}
abstract class MyAbstractClass implements MyInterface{
public abstract void println(); --------(1)
public abstract void print(); --------(2)
public abstract int size();
public boolean isEmpty(){
return size() == 0;
}
}
class MyConcreteClassA extends MyAbstractClass implements MyInterface{ --------(3)
public void print() {
System.out.print("A");
}
public void println() {
System.out.println("A");
}
public int size() {
return 0;
}
}
class MyConcreteClassB extends MyAbstractClass implements MyInterface{ --------(4)
public void print() {
System.out.print("B");
}
public void println() {
System.out.println("B");
}
public int size() {
return 0;
}
}
說明:抽象類MyAbstractClass 的抽象方法(1)和(2)可以不必顯式寫出來。因?yàn)槌橄箢悤^承接口的抽象方法。同時,類MyConcreteClassA 定義中(3)的implements MyInterface{ 也可以不顯式寫出。盡管多了一個中間抽象類MyAbstractClass 層(有些公共方法或者缺省方法已在此實(shí)現(xiàn)),但是還是必須實(shí)現(xiàn)MyInterface中剩下的所有接口方法。
這樣的結(jié)果,很好。所有具體類的公共方法被抽象基類實(shí)現(xiàn)了,同時,具體類也可以覆蓋基類的缺省方法。對于子類是否支持某一個接口方法的解決,在抽象基類中實(shí)現(xiàn)一個缺省的方法更是有效。否則,就算是某一子類不支持該方法,也必須被實(shí)現(xiàn)。比如,你throw了一個 UnsupportedOperationException異常。這樣很不好。
|
posted on 2008-08-14 15:34
zhqh 閱讀(334)
評論(0) 編輯 收藏 所屬分類:
jdk代碼分析