簡體中文 | 繁體中文

大話設計模式-----第153章


如果有下輩子 夢魘無涯 一晚情深:男神老公太危險 冷酷校草戀上甜心校花 前妻來襲 撒旦的復仇新娘 墮落之旅 仙路當空 末法仙宇 鋒凌天下 官家小妾種田記 腹黑狂妃:王爺別亂來 這個遊戲不簡單 鋒行天下 周公解夢 屍家夫君 神女是個男兒身 錯愛在清朝 使命召喚之大炮兵主義 無限之最強人王
第153章

小A:“模板方法模式有什麼缺陷?”

大B:“組合優先於繼承,而模板方法模式是少數幾個必須從非純虛類(C++的稱呼,就是java的interface)繼承來實現的模式之一。新手往往頗費周折才能理解其要義,因為它的複雜性——概念複雜性和實現複雜性。而用IOC模式代替繼承才是降低複雜性的更好方案。1、概念複雜性。從面向物件方法的本質來講,父類負責抽象,子類負責具體。而模板方法恰好反過來了,父類實現了大部分功能,而子類實現少數純虛方法,然後由父類的方法呼叫。違反了面向物件的一般性思維的原因是這個模式的初衷並不是抽象,而是最大限度的重用。2、實現複雜性。這種重用方式的代價就是每個子類身上都揹負了父類強加給它的包袱。”

舉個例子:

publicabstractclassApplicationContext{

protectedStringpath;

publicabstractInputStreamgetStream();

publicvoidbuild(){

getStream();

}

publicApplicationContext(Stringpath){

this.path=path;

}

}

publicclassClassPathContextextendsApplicationContext{

publicClassPathContext(Stringpath){

//super(path)執行之前絕對不能使用path變數,因為父類還沒有初始化。

super(path);//為了能夠執行父類構建器,強加給子類的程式碼。

}

publicInputStreamgetStream(){……}

}

呼叫程式碼:

ApplicationContextcontext=newClassPathContext(“path”);

context.build();

大B:“這裡父類帶給子類的負擔有兩點:1、父類的非預設構建器子類必須重寫。2、子類在構建器裡使用父類的成員變數時要注意順序。由此可見,這個模式在提高重用性的同時也增加了複雜性:1、子類的編寫者必須瞭解父類的實現。2、父類的改動很容易波及到子類。用IOC組合方式進行就漂亮得多,把子類要實現的方法用interface來描述。這時兩個父子關係的類就轉變成呼叫與被呼叫的關係,之間透過interface形成契約。”

publicclassApplicationContext{

Readerreader;

publicvoidsetReader(Readerreader){this.reader=reader;}

publicvoidbuild(){

reader.getStream(path);

}

}

publicinterfaceReader{

publicInputStreamgetStream(Stringpath);

}

呼叫程式碼:

ApplicationContextcontext=newApplicationContext(“path”);

context.setReader(newReaderImpl());

context.build();

大B:“這兩種實現最大的區別是ClassPathContext和ApplicationContext是緊耦合的。而ReaderImpl和ApplicaitonContext是正交的。其次就是IOC方式的實現程式碼要麻煩,這是java嚴謹的語言機制決定的,如果用C#的DelegateMethod來實現要簡潔許多。”

推薦小說