




已閱讀5頁,還剩13頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
面向接口編程詳解(二)編程實(shí)例問題的提出 定義:現(xiàn)在我們要開發(fā)一個(gè)應(yīng)用,模擬移動存儲設(shè)備的讀寫,即計(jì)算機(jī)與U盤、MP3、移動硬盤等設(shè)備進(jìn)行數(shù)據(jù)交換。上下文(環(huán)境):已知要實(shí)現(xiàn)U盤、MP3播放器、移動硬盤三種移動存儲設(shè)備,要求計(jì)算機(jī)能同這三種設(shè)備進(jìn)行數(shù)據(jù)交換,并且以后可能會有新的第三方的移動存儲設(shè)備,所以計(jì)算機(jī)必須有擴(kuò)展性,能與目前未知而以后可能會出現(xiàn)的存儲設(shè)備進(jìn)行數(shù)據(jù)交換。各個(gè)存儲設(shè)備間讀、寫的實(shí)現(xiàn)方法不同,U盤和移動硬盤只有這兩個(gè)方法,MP3Player還有一個(gè)PlayMusic方法。名詞定義:數(shù)據(jù)交換=讀,寫看到上面的問題,我想各位腦子中一定有了不少想法,這是個(gè)很好解決的問題,很多方案都能達(dá)到效果。下面,我列舉幾個(gè)典型的方案。解決方案列舉 方案一:分別定義FlashDisk、MP3Player、MobileHardDisk三個(gè)類,實(shí)現(xiàn)各自的Read和Write方法。然后在Computer類中實(shí)例化上述三個(gè)類,為每個(gè)類分別寫讀、寫方法。例如,為FlashDisk寫ReadFromFlashDisk、WriteToFlashDisk兩個(gè)方法??偣擦鶄€(gè)方法。方案二:定義抽象類MobileStorage,在里面寫虛方法Read和Write,三個(gè)存儲設(shè)備繼承此抽象類,并重寫Read和Write方法。Computer類中包含一個(gè)類型為MobileStorage的成員變量,并為其編寫get/set器,這樣Computer中只需要兩個(gè)方法:ReadData和WriteData,并通過多態(tài)性實(shí)現(xiàn)不同移動設(shè)備的讀寫。方案三:與方案二基本相同,只是不定義抽象類,而是定義接口IMobileStorage,移動存儲器類實(shí)現(xiàn)此接口。Computer中通過依賴接口IMobileStorage實(shí)現(xiàn)多態(tài)性。方案四:定義接口IReadable和IWritable,兩個(gè)接口分別只包含Read和Write,然后定義接口IMobileStorage接口繼承自IReadable和IWritable,剩下的實(shí)現(xiàn)與方案三相同。下面,我們來分析一下以上四種方案:首先,方案一最直白,實(shí)現(xiàn)起來最簡單,但是它有一個(gè)致命的弱點(diǎn):可擴(kuò)展性差?;蛘哒f,不符合“開放-關(guān)閉原則”(注:意為對擴(kuò)展開放,對修改關(guān)閉)。當(dāng)將來有了第三方擴(kuò)展移動存儲設(shè)備時(shí),必須對Computer進(jìn)行修改。這就如在一個(gè)真實(shí)的計(jì)算機(jī)上,為每一種移動存儲設(shè)備實(shí)現(xiàn)一個(gè)不同的插口、并分別有各自的驅(qū)動程序。當(dāng)有了一種新的移動存儲設(shè)備后,我們就要將計(jì)算機(jī)大卸八塊,然后增加一個(gè)新的插口,在編寫一套針對此新設(shè)備的驅(qū)動程序。這種設(shè)計(jì)顯然不可取。此方案的另一個(gè)缺點(diǎn)在于,冗余代碼多。如果有100種移動存儲,那我們的Computer中豈不是要至少寫200個(gè)方法,這是不能接受的!我們再來看方案二和方案三,之所以將這兩個(gè)方案放在一起討論,是因?yàn)樗麄兓臼且粋€(gè)方案(從思想層面上來說),只不過實(shí)現(xiàn)手段不同,一個(gè)是使用了抽象類,一個(gè)是使用了接口,而且最終達(dá)到的目的應(yīng)該是一樣的。我們先來評價(jià)這種方案:首先它解決了代碼冗余的問題,因?yàn)榭梢詣討B(tài)替換移動設(shè)備,并且都實(shí)現(xiàn)了共同的接口,所以不管有多少種移動設(shè)備,只要一個(gè)Read方法和一個(gè)Write方法,多態(tài)性就幫我們解決問題了。而對第一個(gè)問題,由于可以運(yùn)行時(shí)動態(tài)替換,而不必將移動存儲類硬編碼在Computer中,所以有了新的第三方設(shè)備,完全可以替換進(jìn)去運(yùn)行。這就是所謂的“依賴接口,而不是依賴與具體類”,不信你看看,Computer類只有一個(gè)MobileStorage類型或IMobileStorage類型的成員變量,至于這個(gè)變量具體是什么類型,它并不知道,這取決于我們在運(yùn)行時(shí)給這個(gè)變量的賦值。如此一來,Computer和移動存儲器類的耦合度大大下降。那么這里該選抽象類還是接口呢?還記得第一篇文章我對抽象類和接口選擇的建議嗎?看動機(jī)。這里,我們的動機(jī)顯然是實(shí)現(xiàn)多態(tài)性而不是為了代碼復(fù)用,所以當(dāng)然要用接口。最后我們再來看一看方案四,它和方案三很類似,只是將“可讀”和“可寫”兩個(gè)規(guī)則分別抽象成了接口,然后讓IMobileStorage再繼承它們。這樣做,顯然進(jìn)一步提高了靈活性,但是,這有沒有設(shè)計(jì)過度的嫌疑呢?我的觀點(diǎn)是:這要看具體情況。如果我們的應(yīng)用中可能會出現(xiàn)一些類,這些類只實(shí)現(xiàn)讀方法或只實(shí)現(xiàn)寫方法,如只讀光盤,那么這樣做也是可以的。如果我們知道以后出現(xiàn)的東西都是能讀又能寫的,那這兩個(gè)接口就沒有必要了。其實(shí)如果將只讀設(shè)備的Write方法留空或拋出異常,也可以不要這兩個(gè)接口。總之一句話:理論是死的,人是活的,一切從現(xiàn)實(shí)需要來,防止設(shè)計(jì)不足,也要防止設(shè)計(jì)過度。在這里,我們姑且認(rèn)為以后的移動存儲都是能讀又能寫的,所以我們選方案三。實(shí)現(xiàn) 下面,我們要將解決方案加以實(shí)現(xiàn)。我選擇的語言是C#,但是在代碼中不會用到C#特有的性質(zhì),所以使用其他語言的朋友一樣可以參考。首先編寫IMobileStorage接口:Code:IMobileStorage1namespaceInterfaceExample23publicinterfaceIMobileStorage45voidRead();/從自身讀數(shù)據(jù)6voidWrite();/將數(shù)據(jù)寫入自身78代碼比較簡單,只有兩個(gè)方法,沒什么好說的,接下來是三個(gè)移動存儲設(shè)備的具體實(shí)現(xiàn)代碼:U盤Code:FlashDisk1namespaceInterfaceExample23publicclassFlashDisk:IMobileStorage45publicvoidRead()67Console.WriteLine(ReadingfromFlashDisk);8Console.WriteLine(Readfinished!);91011publicvoidWrite()1213Console.WriteLine(WritingtoFlashDisk);14Console.WriteLine(Writefinished!);151617MP3Code:MP3Player1namespaceInterfaceExample23publicclassMP3Player:IMobileStorage45publicvoidRead()67Console.WriteLine(ReadingfromMP3Player);8Console.WriteLine(Readfinished!);91011publicvoidWrite()1213Console.WriteLine(WritingtoMP3Player);14Console.WriteLine(Writefinished!);151617publicvoidPlayMusic()1819Console.WriteLine(Musicisplaying);202122移動硬盤Code:MobileHardDisk1namespaceInterfaceExample23publicclassMobileHardDisk:IMobileStorage45publicvoidRead()67Console.WriteLine(ReadingfromMobileHardDisk);8Console.WriteLine(Readfinished!);91011publicvoidWrite()1213Console.WriteLine(WritingtoMobileHardDisk);14Console.WriteLine(Writefinished!);151617可以看到,它們都實(shí)現(xiàn)了IMobileStorage接口,并重寫了各自不同的Read和Write方法。下面,我們來寫Computer:Code:Computer1namespaceInterfaceExample23publicclassComputer45privateIMobileStorage_usbDrive;67publicIMobileStorageUsbDrive89get1011returnthis._usbDrive;1213set1415this._usbDrive=value;16171819publicComputer()20212223publicComputer(IMobileStorageusbDrive)2425this.UsbDrive=usbDrive;262728publicvoidReadData()2930this._usbDrive.Read();313233publicvoidWriteData()3435this._usbDrive.Write();363738其中的UsbDrive就是可替換的移動存儲設(shè)備,之所以用這個(gè)名字,是為了讓大家覺得直觀,就像我們平常使用電腦上的USB插口插拔設(shè)備一樣。OK!下面我們來測試我們的“電腦”和“移動存儲設(shè)備”是否工作正常。我是用的C#控制臺程序,具體代碼如下:Code:測試代碼1namespaceInterfaceExample23classProgram45staticvoidMain(stringargs)67Computercomputer=newComputer();8IMobileStoragemp3Player=newMP3Player();9IMobileStorageflashDisk=newFlashDisk();10IMobileStoragemobileHardDisk=newMobileHardDisk();1112Console.WriteLine(IinsertedmyMP3Playerintomycomputerandcopysomemusictoit:);13computer.UsbDrive=mp3Player;14computer.WriteData();15Console.WriteLine();1617Console.WriteLine(Well,Ialsowanttocopyagreatmovietomycomputerfromamobileharddisk:);18computer.UsbDrive=mobileHardDisk;19computer.ReadData();20Console.WriteLine();2122Console.WriteLine(OK!Ihavetoreadsomefilesfrommyflashdiskandcopyanotherfiletoit:);23computer.UsbDrive=flashDisk;24computer.ReadData();25computer.WriteData();26Console.ReadLine();272829現(xiàn)在編譯、運(yùn)行程序,如果沒有問題,將看到如下運(yùn)行結(jié)果:圖2.1 各種移動存儲設(shè)備測試結(jié)果好的,看來我們的系統(tǒng)工作良好。 后來 剛過了一個(gè)星期,就有人送來了新的移動存儲設(shè)備NewMobileStorage,讓我測試能不能用,我微微一笑,心想這不是小菜一碟,讓我們看看面向接口編程的威力吧!將測試程序修改成如下:Code:測試代碼1namespaceInterfaceExample23classProgram45staticvoidMain(stringargs)67Computercomputer=newComputer();8IMobileStoragenewMobileStorage=newNewMobileStorage();910Console.WriteLine(Now,Iamtestingthenewmobilestorage:);11computer.UsbDrive=newMobileStorage;12computer.ReadData();13computer.WriteData();14Console.ReadLine();151617編譯、運(yùn)行、看結(jié)果:哈哈,神奇吧,Computer一點(diǎn)都不用改動,就可以使新的設(shè)備正常運(yùn)行。這就是所謂“對擴(kuò)展開放,對修改關(guān)閉”。圖2.2 新設(shè)備擴(kuò)展測試結(jié)果又過了幾天,有人通知我說又有一個(gè)叫SuperStorage的移動設(shè)備要接到我們的Computer上,我心想來吧,管你是“超級存儲”還是“特級存儲”,我的“面向接口編程大法”把你們統(tǒng)統(tǒng)搞定。但是,當(dāng)設(shè)備真的送來,我傻眼了,開發(fā)這個(gè)新設(shè)備的團(tuán)隊(duì)沒有拿到我們的IMobileStorage接口,自然也沒有遵照這個(gè)約定。這個(gè)設(shè)備的讀、寫方法不叫Read和Write,而是叫rd和wt,這下完了不符合接口啊,插不上。但是,不要著急,我們回到現(xiàn)實(shí)來找找解決的辦法。我們一起想想:如果你的Computer上只有USB接口,而有人拿來一個(gè)PS/2的鼠標(biāo)要插上用,你該怎么辦?想起來了吧,是不是有一種叫“PS/2-USB”轉(zhuǎn)換器的東西?也叫適配器,可以進(jìn)行不同接口的轉(zhuǎn)換。對了!程序中也有轉(zhuǎn)換器。這里,我要引入一個(gè)設(shè)計(jì)模式,叫“Adapter”。它的作用就如現(xiàn)實(shí)中的適配器一樣,把接口不一致的兩個(gè)插件接合起來。由于本篇不是講設(shè)計(jì)模式的,而且Adapter設(shè)計(jì)模式很好理解,所以我就不細(xì)講了,先來看我設(shè)計(jì)的類圖吧:如圖所示,雖然SuperStorage沒有實(shí)現(xiàn)IMobileStorage,但我們定義了一個(gè)實(shí)現(xiàn)IMobileStorage的SuperStorageAdapter,它聚合了一個(gè)SuperStorage,并將rd和wt適配為Read和Write,SuperStorageAdapter圖2.3 Adapter模式應(yīng)用示意具體代碼如下:Code:SuperStorageAdapter1namespaceInterfaceExample23publicclassSuperStorageAdapter:IMobileStorage45privateSuperStorage_superStorage;67publicSuperStorageSuperStorage89get1011returnthis._superStorage;1213set1415this._superStorage=value;16171819publicvoidRead()2021this._superStorage.rd();222324publicvoidWrite()2526this._s
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 黨務(wù)面試題目及答案
- 電工分?jǐn)?shù)考試題及答案
- 才華禮物測試題及答案
- 產(chǎn)品公司面試題及答案
- 如何找到適合團(tuán)隊(duì)的管理工具計(jì)劃
- 2025年會計(jì)實(shí)務(wù)高頻考點(diǎn)試題及答案
- 財(cái)務(wù)管理考試心得體會總結(jié)試題及答案
- 財(cái)務(wù)管理中的成本效益衡量標(biāo)準(zhǔn)試題及答案
- 2025年工程法規(guī)考試應(yīng)試策略試題及答案
- 財(cái)務(wù)管理實(shí)施中的常見誤區(qū)試題及答案
- 2024年中高考必背文言文74篇
- T-CSUS 69-2024 智慧水務(wù)技術(shù)標(biāo)準(zhǔn)
- 金匱要略知到智慧樹章節(jié)測試課后答案2024年秋浙江中醫(yī)藥大學(xué)
- 電力運(yùn)維平臺需求說明書
- 北京師范大學(xué)《文學(xué)概論》2022-2023學(xué)年第一學(xué)期期末試卷
- 2024年度餐飲業(yè)會員管理服務(wù)合同:顧客權(quán)益與會員服務(wù)的具體規(guī)定3篇
- 2023年高考真題-歷史(遼寧卷) 含解析
- 消防安全應(yīng)急照明設(shè)計(jì)方案
- 學(xué)校校園裝修改造工程施工組織設(shè)計(jì)方案
- 論持久戰(zhàn)全文(完整)
- 2024年河北省中職高考對口升學(xué)考試語文試卷真題(打印版)
評論
0/150
提交評論