0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

《程序設(shè)計(jì)與數(shù)據(jù)結(jié)構(gòu)》——框架與重用

AGk5_ZLG_zhiyua ? 來源:未知 ? 作者:佚名 ? 2017-10-10 10:55 ? 次閱讀

周立功教授數(shù)年之心血之作《程序設(shè)計(jì)與數(shù)據(jù)結(jié)構(gòu)》以及《面向AMetal框架與接口編程(上)》,電子版已無償性分享到電子工程師與高校群體,。書本內(nèi)容公開后,在電子行業(yè)掀起一片學(xué)習(xí)熱潮。經(jīng)周立功教授授權(quán),本公眾號特對《程序設(shè)計(jì)與數(shù)據(jù)結(jié)構(gòu)》一書內(nèi)容進(jìn)行連載,愿共勉之。

第四章為面向?qū)ο缶幊?/span>,本文為 4.5框架與重用

重用不僅限于軟件,比如,貝多芬在他的66號作品中,就重用了另一個(gè)偉大作曲家莫扎特的音樂。他從莫扎特的歌曲《魔笛》第22場中,借用了詠嘆調(diào)“一個(gè)女朋友”,然后在該詠嘆調(diào)中為鋼琴師配樂的大提琴家寫了一連串7個(gè)變奏。

代碼重用的問題與所有的設(shè)計(jì)方法一樣,代碼的可用性和可重用性取決于它是如何設(shè)計(jì)和實(shí)現(xiàn)的。雖然代碼重用并不是OO設(shè)計(jì)所專有的,但OO方法確實(shí)提供了一些機(jī)制,有利于可重用代碼的開發(fā)。

>>> 4.5.1 框架

框架被定義為“一組相互協(xié)作的類,形成某類軟件的一個(gè)可復(fù)用設(shè)計(jì)??蚣軐⒃O(shè)計(jì)劃分為一組抽象類,并定義它們各自的職責(zé)和相互之間的協(xié)作,以此指導(dǎo)體系結(jié)構(gòu)級的設(shè)計(jì),開發(fā)者通過繼承框架中的類和組合其實(shí)例定制該框架以生成特定的應(yīng)用。”

從某種意義上來說,框架是可以通過某種回調(diào)機(jī)制進(jìn)行擴(kuò)展的軟件系統(tǒng)或子系統(tǒng)的半成品。也就是說,首先,框架是半成品,這是它和其它所有軟件組件的本質(zhì)區(qū)別。而某種回調(diào)機(jī)制,通常面向過程編程使用函數(shù)指針作為參數(shù)實(shí)現(xiàn)回調(diào)機(jī)制,比如,冒泡排序和快速排序中的compare的形參就是一個(gè)函數(shù)指針,開發(fā)者只需知道自己實(shí)現(xiàn)特定的比較函數(shù)即可。而面向?qū)ο罂蚣艿慕M成部分包括具體類、抽象類和接口,使用抽象方法——多態(tài)支持回調(diào)機(jī)制實(shí)現(xiàn)逆向工程。

顯然,創(chuàng)建可重用代碼的一種方法就是創(chuàng)建框架,框架規(guī)定應(yīng)用的體系結(jié)構(gòu),它定義了整體結(jié)構(gòu),類和對象的分割,各部分的主要職責(zé),類和對象如何協(xié)作,以及控制流程。框架預(yù)定義了這些設(shè)計(jì)參數(shù),便于設(shè)計(jì)者聚焦于應(yīng)用本身的特定細(xì)節(jié)。但框架使開發(fā)程序變得更加容易,因此程序設(shè)計(jì)需要的許多能力都來源于大量可用的框架。

與代碼重用緊密相關(guān)的一個(gè)概念是標(biāo)準(zhǔn)化,有時(shí)也稱為即插即用,框架思想圍繞的就是這些即插即用和重用原則。在GUI應(yīng)用程序中,用戶界面視為視圖。而實(shí)際上在MVC框架中,視圖是一個(gè)接口,一個(gè)抽象的概念,因此視圖可能是一個(gè)用戶界面,也可能是一個(gè)終端,但只要實(shí)現(xiàn)了update接口的類,都可以將它們看作視圖,從而全面擴(kuò)展了MVC框架的應(yīng)用范圍。因?yàn)闊o論怎么改變,MVC框架的模型與視圖始終是不變的,可變的是具體模型和具體視圖。

以溫控器為例,通過傳感器的溫度檢測是具體模型,而監(jiān)聽傳感器的LED數(shù)碼管和蜂鳴器是具體視圖。當(dāng)溫度達(dá)到或超過上限值時(shí),則數(shù)碼管更新顯示,LED持續(xù)閃爍,蜂鳴器持續(xù)報(bào)警。根據(jù)開閉原則,可以繼續(xù)重用MVC框架的抽象模型與視圖。如果后續(xù)只要開發(fā)與溫度檢測相關(guān)的系列產(chǎn)品,就可以重用該溫度檢測模型。

如果設(shè)計(jì)的系統(tǒng)必須使用不可移植的代碼,那么應(yīng)該將這些代碼抽象到類中,通過抽象將這些不可移植的代碼隔離到各自的類中。比如,針對基于M0+、M3、M4、ARM9、A7、A8內(nèi)核的ARM和DSP的不兼容性,周立功單片機(jī)公司開發(fā)的AWetal和AWorks就是一個(gè)將所有的接口、外圍器件和組件全部都實(shí)現(xiàn)歸一化,且與MCU和OS完全無關(guān)的框架,從而實(shí)現(xiàn)了“一次編程、終生使用、跨平臺”,詳見《面向接口的編程》系列圖書。

由此可見,由于軟件的整體框架結(jié)構(gòu)是一樣的,因此用戶不必學(xué)習(xí)新的框架;其次,開發(fā)人員只要遵循框架文檔提供的類或類庫的公共接口,以及應(yīng)用編程接口API等規(guī)則,就可以充分利用原有的代碼。

>>> 4.5.2 契約

抽象類與接口是實(shí)現(xiàn)代碼重用的強(qiáng)大機(jī)制,為一個(gè)重要的概念“契約”奠定了基礎(chǔ)。那什么是契約?契約是兩方或多方完成或不完成某個(gè)指定工作所達(dá)成的協(xié)議——這是一個(gè)由法律保證的協(xié)定,因此契約是要求開發(fā)人員遵守應(yīng)用編程接口規(guī)范所需的機(jī)制。

一般來說,API就是指一個(gè)框架,開發(fā)人員使用API時(shí),必須遵守框架所定義的規(guī)則。比如,方法名和參數(shù)個(gè)數(shù)等。如果沒有強(qiáng)制性的措施,一些比較差勁的程序員可能會私下編寫他自己的代碼,而不使用框架提供的規(guī)范。如果人們總是忽視或不考慮標(biāo)準(zhǔn)化,那么標(biāo)準(zhǔn)也就沒有什么意義了。

面向?qū)ο蟮脑O(shè)計(jì)一個(gè)重要的目標(biāo)就是將接口從實(shí)現(xiàn)中分離出來,一個(gè)類的接口提供了它的外部視圖,記錄了所有相關(guān)對象的共同屬性和行為。其強(qiáng)調(diào)的是抽象,隱藏了它的屬性和行為的秘密,不需要提供其內(nèi)部關(guān)于該操作的實(shí)現(xiàn)(結(jié)構(gòu))。

接口在很大程度上可以認(rèn)為是類的外部視圖的設(shè)計(jì)者和類的內(nèi)部實(shí)現(xiàn)的實(shí)現(xiàn)者之間的一種“契約”,同時(shí)也是需要(使用)該接口的類(如調(diào)用該接口所提供的操作)和提供該接口的類之間的一種約定。即將一個(gè)較大問題的不同功能通過子契約被分解為小問題,沒有別的情況比在設(shè)計(jì)類時(shí)更能體現(xiàn)這種思想。一個(gè)單獨(dú)的對象就是一個(gè)具體的實(shí)體,在系統(tǒng)中扮演某個(gè)角色。

將接口從實(shí)現(xiàn)中分離出來是通過抽象類來實(shí)現(xiàn)的,抽象類包含一個(gè)或多個(gè)沒有提供任何具體實(shí)現(xiàn)的方法。Validator之所以是一個(gè)抽象類,因?yàn)闊o法對它實(shí)例化。比如:

這與契約有什么關(guān)系?首先,希望所有與視圖對應(yīng)的顯示函數(shù)都使用相同的語法調(diào)用,比如,實(shí)現(xiàn)的每一種視圖都包含一個(gè)名為validate的方法。其次,每個(gè)類都要對自己的動作負(fù)責(zé),因此類不僅要提供相應(yīng)的方法,還必須提供它自己的實(shí)現(xiàn)代碼。比如:

由此可見,采用這種方式,就有了一個(gè)真正多態(tài)的Validator框架。系統(tǒng)中每個(gè)與視圖對應(yīng)的顯示函數(shù)都可以調(diào)用validaate方法,而調(diào)用每個(gè)與視圖對應(yīng)的顯示函數(shù)時(shí)都會得到不同的結(jié)果。實(shí)際上,向一個(gè)對象發(fā)送一個(gè)消息時(shí),會根據(jù)對象的不同而產(chǎn)生不同的響應(yīng),這正是多態(tài)的根本所在。

>>> 4.5.3 建立契約

定義契約的規(guī)則是通過抽象類提供一個(gè)未實(shí)現(xiàn)的方法,當(dāng)設(shè)計(jì)一個(gè)子類實(shí)現(xiàn)某個(gè)契約時(shí),它必須為父類中未實(shí)現(xiàn)的方法提供實(shí)現(xiàn),因?yàn)槠跫s帶來的好處可以標(biāo)準(zhǔn)化代碼。如果開發(fā)人員不遵循契約設(shè)計(jì)類,那么使用類的所有人都必須查看文檔。比如:

雖然這樣做也能夠?qū)崿F(xiàn)范圍值和奇偶校驗(yàn)功能,但不符合契約。因?yàn)槊嫦驅(qū)ο蟮闹饕獌?yōu)勢之一是可以重用類,重用的高層次的抽象接口比高度具體的接口更有用。

>>> 4.5.4 教條的危害

著名的語言專家王垠認(rèn)為,“很多編程的人喜歡鼓吹各種各樣的原則,并將那些所謂的原則奉為教條或者秘方。以為兢兢業(yè)業(yè)地遵循這些原則,空喊幾句口號,就可以寫出好的代碼。同時(shí)對違反這些原則的人嗤之以鼻——你不知道,不遵循或藐視這些原則,那么你就是菜鳥?!币虼瞬灰つ康孛孕鸥鞣N各樣的原則,比如,DRY原則(Don’t Repeat Yourself,不要重復(fù)你自己)在實(shí)際的工程中帶來了各種各樣的問題,卻經(jīng)常被忽視。DRY原則說,如果你發(fā)現(xiàn)重復(fù)的代碼,就提取它們?yōu)橐粋€(gè)父類。 然而“避免重復(fù)”并不等于“抽象”,有時(shí)候適當(dāng)?shù)闹貜?fù)代碼是有好處的。

代碼的“抽象”和它的“可讀性”,其實(shí)是相互矛盾的關(guān)系。適度的抽象和避免重復(fù)可以提高代碼的可讀性,如果你盡“一切可能”從代碼里提取共性,甚至將一些微不足道的“共性”也提出“共享”,反而破壞了程序的可閱讀性。如果盲目地將以下代碼:

修改為:

當(dāng)你看到TypeA和TypeB的定義時(shí),再也不能一目了然地看到int a。其實(shí)完全沒有必要提取這中無關(guān)緊要的共性,造出一個(gè)新的父類,因?yàn)榭梢娦允浅绦騿T產(chǎn)生直覺的關(guān)鍵。奉行DRY原則的人存在的問題,在于是他們隨時(shí)都在試圖發(fā)現(xiàn)“將來可能重用”的代碼,而不是等到真的出現(xiàn)重復(fù)的時(shí)候再去做抽象。

抽象思想的關(guān)鍵在于“發(fā)現(xiàn)兩個(gè)東西是一樣的”,然而很多時(shí)候,開始時(shí)覺得兩個(gè)東西是一回事,最后發(fā)現(xiàn)它們其實(shí)只是膚淺的相似,而本質(zhì)完全不同。同一個(gè)int a,其實(shí)可以表示很多種風(fēng)馬牛不及的性質(zhì)。你看到都是int a就提出來為父類,反而讓程序的概念變得混亂。有些東西開始時(shí)貌似同類,當(dāng)添加了新的邏輯之后,發(fā)現(xiàn)它們的用途開始特殊化了。因此過早地提取共性,反而捆住了手腳,為了所謂的“一致性”,而重復(fù)一些沒用的東西。這樣的一致性,其實(shí)還不如針對每種情況分別做特殊處理。

防止過早抽象的方法其實(shí)很簡單,它的名字叫做“等待”。其實(shí)就算你不重用代碼,也不會影響程序的準(zhǔn)確性和可讀性,時(shí)間能夠告訴你一切。如果你發(fā)現(xiàn)自己仿佛正在重復(fù)以前寫過代碼,請先不要停下來,堅(jiān)持將這段重復(fù)的代碼寫完。如果你不將它寫出來,你將無法準(zhǔn)確地發(fā)現(xiàn)重復(fù)的代碼,因?yàn)樗鼈兒苡锌赡艿阶詈笃鋵?shí)是不一樣的。

我們應(yīng)該避免沒有實(shí)際效果的抽象,如果代碼才重復(fù)了兩次,就開始提取共性,也許到最后會發(fā)現(xiàn),這個(gè)模板總共也就只用了兩次。只重復(fù)了兩次的代碼,大部分時(shí)候是不值得為它提取模板的。因?yàn)槟0灞旧硪彩谴a,而且抽象思考本身是需要一定代價(jià)的。所以最后總的開銷,也許還不如就讓那兩段重復(fù)的代碼待在里面。

而優(yōu)秀的程序員等到事實(shí)證明重用一定會帶來好處時(shí),才會開始提取共性進(jìn)行抽象。實(shí)踐經(jīng)驗(yàn)證明,每一次積極地尋找抽象,最后的結(jié)果都是制造一些不必要的框架,搞得自己的代碼自己都看不懂。如果過度地強(qiáng)調(diào)DRY,強(qiáng)調(diào)代碼的“重用”,隨時(shí)隨地想著抽象,結(jié)果就會被這些抽象攪混了頭腦,bug百出寸步難行。如果你不能寫出“可用”的代碼,又何談“可重用”的代碼呢?

其實(shí)人們寫程序本來自然而然就會在合適的時(shí)候進(jìn)行抽象避免重復(fù),因此千萬不要迷信某個(gè)大師或?qū)<移鹆艘粋€(gè)DRY這樣的名字,就將我們繞進(jìn)去了,反而使我們喪失了透過現(xiàn)象看本質(zhì)的思維能力。

回頭來看,里氏替換原則也沒有什么特別之處,無論是否有人提出這樣的原則,子類對象與父類對象的地址值相等且類型相同,這是在語言層面天生就支持的行為。比如,雖然&rangeValidator與&rangeValidator.isa的類型不同,但它們的值相等。由于&rangeValidator.isa與pThis不僅類型相同它們的值相等,因此子類對象替換父類對象也就成為了事實(shí)。

當(dāng)你看透了問題的本質(zhì)之后,也就具備了洞穿一切的能力。顯然里氏替換原則只是套了一個(gè)馬甲而已,因此人們常說,“盡信書不如無書”,由此可見不無道理。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴

原文標(biāo)題:周立功:盡信書不如無書

文章出處:【微信號:ZLG_zhiyuan,微信公眾號:ZLG致遠(yuǎn)電子】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》周立功數(shù)十年心血力作

    為了將實(shí)際開發(fā)過程中總結(jié)的有價(jià)值的技術(shù)應(yīng)用分享給大家,周立功及其團(tuán)隊(duì)整理出《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》這本書,其內(nèi)容如同培訓(xùn)講師的教案,是周立功和團(tuán)隊(duì)的讀書筆記和程序設(shè)計(jì)實(shí)踐的心得。
    發(fā)表于 05-26 10:06 ?29次閱讀

    周立功“程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)”:深度解剖動態(tài)分布內(nèi)存的free()函數(shù)與realloc()函數(shù)

    周立功教授數(shù)年之心血之作《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》,書本內(nèi)容公開后,在電子行業(yè)掀起一片學(xué)習(xí)熱潮。
    的頭像 發(fā)表于 08-25 14:22 ?1.5w次閱讀

    新書創(chuàng)作談:周立功教授數(shù)十年之心血力作《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)

    ` 近日,周立功教授公開了數(shù)十年之心血力作《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》,此書在4月28日落筆,電子版已無償性分享到電子工程師與高校群體,在致遠(yuǎn)電子公眾號后臺回復(fù)關(guān)鍵字【程序設(shè)計(jì)】可在線閱讀。 在程序
    發(fā)表于 05-15 18:04

    【完整資料】《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》周立功數(shù)十年心血力作

    `近日,周立功教授公開了數(shù)十年之心血力作《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》,此書在4月28日落筆,電子版已無償性分享到電子工程師與高校群體。在程序設(shè)計(jì)過程中,很多開發(fā)人員在沒有全局思維的把控,科學(xué)、系統(tǒng)的組織
    發(fā)表于 05-16 16:43

    程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)

    本帖最后由 lee_st 于 2017-10-31 09:04 編輯 程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)(僅供閱覽不可印刷)
    發(fā)表于 10-21 20:09

    程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)

    本帖最后由 lee_st 于 2018-6-16 02:32 編輯 程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)(僅供閱覽不可印刷)
    發(fā)表于 06-15 02:33

    程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》【完整資料】分享!

    現(xiàn)象,甚至成為一位閱讀程序者。 為了將實(shí)際開發(fā)過程中總結(jié)的有價(jià)值的技術(shù)應(yīng)用分享給大家,周立功及其團(tuán)隊(duì)整理出《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》這本書,其內(nèi)容如同培訓(xùn)講師的教案,是周立功和團(tuán)隊(duì)的讀書筆記和程序
    發(fā)表于 08-31 16:20

    數(shù)據(jù)結(jié)構(gòu)及應(yīng)用算法教學(xué)課件

    課程簡介 《數(shù)據(jù)結(jié)構(gòu)》作為一門獨(dú)立的課程最早是美國的一些大學(xué)開設(shè)的,1968年美國唐·歐·克努特教授開創(chuàng)了數(shù)據(jù)結(jié)構(gòu)的最初體系,他所著的《計(jì)算機(jī)程序設(shè)計(jì)技巧》第
    發(fā)表于 09-05 11:24 ?0次下載

    C++數(shù)據(jù)結(jié)構(gòu)程序設(shè)計(jì)(中文版)

    數(shù)據(jù)結(jié)構(gòu)英文版第二版對應(yīng)中文教材,請取用
    發(fā)表于 10-30 17:53 ?0次下載

    新書創(chuàng)作談:周立功教授數(shù)十年之心血力作《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)

    近日,周立功教授公開了數(shù)十年之心血力作《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》,此書在4月28日落筆,電子版已無償性分享到電子工程師與高校群體,在致遠(yuǎn)電子公眾號后臺回復(fù)關(guān)鍵字【程序設(shè)計(jì)】可在線閱讀。
    發(fā)表于 05-08 09:32 ?2004次閱讀

    算法與數(shù)據(jù)結(jié)構(gòu)——哈希表

    周立功教授數(shù)年之心血之作《程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》以及《面向第三章為算法與數(shù)據(jù)結(jié)構(gòu),本文為3.5 哈希表。
    的頭像 發(fā)表于 09-25 11:37 ?5496次閱讀
    算法與<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>——哈希表

    程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)》——什么是類?

    將具有相同數(shù)據(jù)結(jié)構(gòu)(屬性)和行為(操作)的對象歸在一起為一個(gè)類,屬于類的任何對象都共享該類的所有屬性,這就是類的來源。
    的頭像 發(fā)表于 10-10 10:52 ?7842次閱讀
    《<b class='flag-5'>程序設(shè)計(jì)</b>與<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>》——什么是類?

    嵌入式軟件工程電子書之周立功程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)

    本文詳細(xì)介紹了嵌入式軟件工程中的程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)相關(guān)知識。 在學(xué)習(xí)程序設(shè)計(jì)時(shí),很多初學(xué)者常常會陷入這樣的誤區(qū),他們總將阻礙個(gè)人成長的原因歸結(jié)為缺少機(jī)會。其實(shí)問題的根源在于缺乏方法論,很少有人將
    發(fā)表于 10-25 17:45 ?4次下載

    什么是數(shù)據(jù)結(jié)構(gòu)?為什么要學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)?數(shù)據(jù)結(jié)構(gòu)的應(yīng)用實(shí)例分析

    本文檔的主要內(nèi)容詳細(xì)介紹的是什么是數(shù)據(jù)結(jié)構(gòu)?為什么要學(xué)習(xí)數(shù)據(jù)結(jié)構(gòu)?數(shù)據(jù)結(jié)構(gòu)的應(yīng)用實(shí)例分析包括了:數(shù)據(jù)結(jié)構(gòu)在串口通信當(dāng)中的應(yīng)用,數(shù)據(jù)結(jié)構(gòu)在按鍵
    發(fā)表于 09-26 15:45 ?14次下載
    什么是<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>?為什么要學(xué)習(xí)<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>?<b class='flag-5'>數(shù)據(jù)結(jié)構(gòu)</b>的應(yīng)用實(shí)例分析

    程序設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)(嵌入式)

    編程的基礎(chǔ)-算法和數(shù)據(jù)結(jié)構(gòu)入門資料免費(fèi)下載。
    發(fā)表于 04-18 09:35 ?1次下載