<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關(guān)鍵字專題1關(guān)鍵字專題50關(guān)鍵字專題500關(guān)鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關(guān)鍵字專題關(guān)鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        學(xué)習JavaScript設(shè)計模式(多態(tài))_javascript技巧

        來源:懂視網(wǎng) 責編:小采 時間:2020-11-27 21:46:10
        文檔

        學(xué)習JavaScript設(shè)計模式(多態(tài))_javascript技巧

        學(xué)習JavaScript設(shè)計模式(多態(tài))_javascript技巧:多態(tài)的實際含義是:同一操作作用于不同的對象上面,可以產(chǎn)生不同的解釋和不同的執(zhí)行結(jié)果。換句話說,給不同的對象發(fā)送同一個消息的時候,這些對象會根據(jù)這個消息分別給出不同的反饋。 從字面上來理解多態(tài)不太容易,下面我們來舉例說明一下。 主人家里養(yǎng)了兩只
        推薦度:
        導(dǎo)讀學(xué)習JavaScript設(shè)計模式(多態(tài))_javascript技巧:多態(tài)的實際含義是:同一操作作用于不同的對象上面,可以產(chǎn)生不同的解釋和不同的執(zhí)行結(jié)果。換句話說,給不同的對象發(fā)送同一個消息的時候,這些對象會根據(jù)這個消息分別給出不同的反饋。 從字面上來理解多態(tài)不太容易,下面我們來舉例說明一下。 主人家里養(yǎng)了兩只

        多態(tài)的實際含義是:同一操作作用于不同的對象上面,可以產(chǎn)生不同的解釋和不同的執(zhí)行結(jié)果。換句話說,給不同的對象發(fā)送同一個消息的時候,這些對象會根據(jù)這個消息分別給出不同的反饋。

        從字面上來理解多態(tài)不太容易,下面我們來舉例說明一下。

        主人家里養(yǎng)了兩只動物,分別是一只鴨和一只雞,當主人向它們發(fā)出“叫”的命令時,鴨會“嘎嘎嘎”地叫,而雞會“咯咯咯”地叫。這兩只動物都會以自己的方式來發(fā)出叫聲。它們同樣“都是動物,并且可以發(fā)出叫聲”,但根據(jù)主人的指令,它們會各自發(fā)出不同的叫聲。

        其實,其中就蘊含了多態(tài)的思想。下面我們通過代碼進行具體的介紹。

        1. 一段“多態(tài)”的JavaScript代碼

        我們把上面的故事用JavaScript代碼實現(xiàn)如下:

        這段代碼確實體現(xiàn)了“多態(tài)性”,當我們分別向鴨和雞發(fā)出“叫喚”的消息時,它們根據(jù)此消息作出了各自不同的反應(yīng)。但這樣的“多態(tài)性”是無法令人滿意的,如果后來又增加了一只動物,比如狗,顯然狗的叫聲是“汪汪汪”,此時我們必須得改動makeSound函數(shù),才能讓狗也發(fā)出叫聲。修改代碼總是危險的,修改的地方越多,程序出錯的可能性就越大,而且當動物的種類越來越多時,makeSound有可能變成一個巨大的函數(shù)。

        多態(tài)背后的思想是將“做什么”和“誰去做以及怎樣去做”分離開來,也就是將“不變的事物”與 “可能改變的事物”分離開來。在這個故事中,動物都會叫,這是不變的,但是不同類型的動物具體怎么叫是可變的。把不變的部分隔離出來,把可變的部分封裝起來,這給予了我們擴展程序的能力,程序看起來是可生長的,也是符合開放-封閉原則的,相對于修改代碼來說,僅僅增加代碼就能完成同樣的功能,這顯然優(yōu)雅和安全得多。

        2. 對象的多態(tài)性

        下面是改寫后的代碼,首先我們把不變的部分隔離出來,那就是所有的動物都會發(fā)出叫聲:

        然后把可變的部分各自封裝起來,我們剛才談到的多態(tài)性實際上指的是對象的多態(tài)性:

        現(xiàn)在我們向鴨和雞都發(fā)出“叫喚”的消息,它們接到消息后分別作出了不同的反應(yīng)。如果有一天動物世界里又增加了一只狗,這時候只要簡單地追加一些代碼就可以了,而不用改動以前的makeSound函數(shù),如下所示:

        3. 類型檢查和多態(tài)

        類型檢查是在表現(xiàn)出對象多態(tài)性之前的一個繞不開的話題,但JavaScript是一門不必進行類型檢查的動態(tài)類型語言,為了真正了解多態(tài)的目的,我們需要轉(zhuǎn)一個彎,從一門靜態(tài)類型語言說起。

        靜態(tài)類型語言在編譯時會進行類型匹配檢查。以Java為例,由于在代碼編譯時要進行嚴格的類型檢查,所以不能給變量賦予不同類型的值,這種類型檢查有時候會讓代碼顯得僵硬,代碼如下:

        現(xiàn)在我們嘗試把上面讓鴨子和雞叫喚的例子換成Java代碼:

        輸出:嘎嘎嘎 } }

        我們已經(jīng)順利地讓鴨子可以發(fā)出叫聲,但如果現(xiàn)在想讓雞也叫喚起來,我們發(fā)現(xiàn)這是一件不可能實現(xiàn)的事情。因為(1)處AnimalSound類的makeSound方法,被我們規(guī)定為只能接受Duck類型的參數(shù):

        某些時候,在享受靜態(tài)語言類型檢查帶來的安全性的同時,我們亦會感覺被束縛住了手腳。

        為了解決這一問題,靜態(tài)類型的面向?qū)ο笳Z言通常被設(shè)計為可以向上轉(zhuǎn)型:當給一個類變量賦值時,這個變量的類型既可以使用這個類本身,也可以使用這個類的超類。這就像我們在描述天上的一只麻雀或者一只喜鵲時,通常說“一只麻雀在飛”或者“一只喜鵲在飛”。但如果想忽略它們的具體類型,那么也可以說”一只鳥在飛“。

        同理,當Duck對象和Chicken對象的類型都被隱藏在超類型Animal身后,Duck對象和Chicken對象就能被交換使用,這是讓對象表現(xiàn)出多態(tài)性的必經(jīng)之路,而多態(tài)性的表現(xiàn)正是實現(xiàn)眾多設(shè)計模式的目標。

        4. 使用繼承得到多態(tài)效果

        使用繼承來得到多態(tài)效果,是讓對象表現(xiàn)出多態(tài)性的最常用手段。繼承通常包括實現(xiàn)繼承和接口繼承。本節(jié)我們討論實現(xiàn)繼承,接口繼承的例子請參見第21章。

        我們先創(chuàng)建一個Animal抽象類,再分別讓Duck和Chicken都繼承自Animal抽象類,下述代碼中(1)處和(2)處的賦值語句顯然是成立的,因為鴨子和雞也是動物:

        現(xiàn)在剩下的就是讓AnimalSound類的makeSound方法接受Animal類型的參數(shù),而不是具體的Duck類型或者Chicken類型:

        輸出嘎嘎嘎 animalSound.makeSound( chicken ); //輸出咯咯咯 } }

        5. JavaScript的多態(tài)

        從前面的講解我們得知,多態(tài)的思想實際上是把“做什么”和“誰去做”分離開來,要實現(xiàn)這一點,歸根結(jié)底先要消除類型之間的耦合關(guān)系。如果類型之間的耦合關(guān)系沒有被消除,那么我們在makeSound方法中指定了發(fā)出叫聲的對象是某個類型,它就不可能再被替換為另外一個類型。在Java中,可以通過向上轉(zhuǎn)型來實現(xiàn)多態(tài)。

        而JavaScript的變量類型在運行期是可變的。一個JavaScript對象,既可以表示Duck類型的對象,又可以表示Chicken類型的對象,這意味著JavaScript對象的多態(tài)性是與生俱來的。

        這種與生俱來的多態(tài)性并不難解釋。JavaScript作為一門動態(tài)類型語言,它在編譯時沒有類型檢查的過程,既沒有檢查創(chuàng)建的對象類型,又沒有檢查傳遞的參數(shù)類型。在2節(jié)的代碼示例中,我們既可以往makeSound函數(shù)里傳遞duck對象當作參數(shù),也可以傳遞chicken對象當作參數(shù)。

        由此可見,某一種動物能否發(fā)出叫聲,只取決于它有沒有makeSound方法,而不取決于它是否是某種類型的對象,這里不存在任何程度上的“類型耦合”。這正是我們從上一節(jié)的鴨子類型中領(lǐng)悟的道理。在JavaScript中,并不需要諸如向上轉(zhuǎn)型之類的技術(shù)來取得多態(tài)的效果。

        6. 多態(tài)在面向?qū)ο蟪绦蛟O(shè)計中的作用

        有許多人認為,多態(tài)是面向?qū)ο缶幊陶Z言中最重要的技術(shù)。但我們目前還很難看出這一點,畢竟大部分人都不關(guān)心雞是怎么叫的,也不想知道鴨是怎么叫的。讓雞和鴨在同一個消息之下發(fā)出不同的叫聲,這跟程序員有什么關(guān)系呢?

        Martin Fowler在《重構(gòu):改善既有代碼的設(shè)計》里寫到:

        多態(tài)的最根本好處在于,你不必再向?qū)ο笤儐枴澳闶鞘裁搭愋汀倍蟾鶕?jù)得到的答案調(diào)用對象的某個行為——你只管調(diào)用該行為就是了,其他的一切多態(tài)機制都會為你安排妥當。

        換句話說,多態(tài)最根本的作用就是通過把過程化的條件分支語句轉(zhuǎn)化為對象的多態(tài)性,從而消除這些條件分支語句。

        Martin Fowler的話可以用下面這個例子很好地詮釋:

        在電影的拍攝現(xiàn)場,當導(dǎo)演喊出“action”時,主角開始背臺詞,照明師負責打燈光,后面的群眾演員假裝中槍倒地,道具師往鏡頭里撒上雪花。在得到同一個消息時,每個對象都知道自己應(yīng)該做什么。如果不利用對象的多態(tài)性,而是用面向過程的方式來編寫這一段代碼,那么相當于在電影開始拍攝之后,導(dǎo)演每次都要走到每個人的面前,確認它們的職業(yè)分工(類型),然后告訴他們要做什么。如果映射到程序中,那么程序中將充斥著條件分支語句。

        利用對象的多態(tài)性,導(dǎo)演在發(fā)布消息時,就不必考慮各個對象接到消息后應(yīng)該做什么。對象應(yīng)該做什么并不是臨時決定的,而是已經(jīng)事先約定和排練完畢的。每個對象應(yīng)該做什么,已經(jīng)成為了該對象的一個方法,被安裝在對象的內(nèi)部,每個對象負責它們自己的行為。所以這些對象可以根據(jù)同一個消息,有條不紊地分別進行各自的工作。

        將行為分布在各個對象中,并讓這些對象各自負責自己的行為,這正是面向?qū)ο笤O(shè)計的優(yōu)點。

        再看一個現(xiàn)實開發(fā)中遇到的例子,這個例子的思想和動物叫聲的故事非常相似。

        假設(shè)我們要編寫一個地圖應(yīng)用,現(xiàn)在有兩家可選的地圖API提供商供我們接入自己的應(yīng)用。目前我們選擇的是谷歌地圖,谷歌地圖的API中提供了show方法,負責在頁面上展示整個地圖。示例代碼如下:

        輸出: 開始渲染google地圖

        后來因為某些原因,要把谷歌地圖換成百度地圖,為了讓renderMap函數(shù)保持一定的彈性,我們用一些條件分支來讓renderMap函數(shù)同時支持谷歌地圖和百度地圖:

        輸出: 開始渲染google地圖 renderMap( 'baidu' ); // 輸出: 開始渲染baidu地圖

        可以看到,雖然renderMap函數(shù)目前保持了一定的彈性,但這種彈性是很脆弱的,一旦需要替換成搜搜地圖,那無疑必須得改動renderMap函數(shù),繼續(xù)往里面堆砌條件分支語句。

        我們還是先把程序中相同的部分抽象出來,那就是顯示某個地圖:

        輸出: 開始渲染google地圖 renderMap( baiduMap ); // 輸出: 開始渲染baidu地圖

        現(xiàn)在來找找這段代碼中的多態(tài)性。當我們向谷歌地圖對象和百度地圖對象分別發(fā)出“展示地圖”的消息時,會分別調(diào)用它們的show方法,就會產(chǎn)生各自不同的執(zhí)行結(jié)果。對象的多態(tài)性提示我們,“做什么”和“怎么去做”是可以分開的,即使以后增加了搜搜地圖,renderMap函數(shù)仍然不需要做任何改變,如下所示:

        輸出: 開始渲染soso地圖

        在這個例子中,我們假設(shè)每個地圖API提供展示地圖的方法名都是show,在實際開發(fā)中也許不會如此順利,這時候可以借助適配器模式來解決問題。

        聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        學(xué)習JavaScript設(shè)計模式(多態(tài))_javascript技巧

        學(xué)習JavaScript設(shè)計模式(多態(tài))_javascript技巧:多態(tài)的實際含義是:同一操作作用于不同的對象上面,可以產(chǎn)生不同的解釋和不同的執(zhí)行結(jié)果。換句話說,給不同的對象發(fā)送同一個消息的時候,這些對象會根據(jù)這個消息分別給出不同的反饋。 從字面上來理解多態(tài)不太容易,下面我們來舉例說明一下。 主人家里養(yǎng)了兩只
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 男人都懂www深夜免费网站| 四虎影视久久久免费| 98精品全国免费观看视频| 亚洲日韩v无码中文字幕| 国产成年无码久久久免费| 国产亚洲精品美女久久久| 少妇性饥渴无码A区免费| 亚洲国产天堂久久综合网站| 久久久久国色av免费看| 老汉色老汉首页a亚洲| 亚洲免费在线视频观看| 亚洲高清中文字幕免费| 日本一线a视频免费观看| 一级成人a免费视频| 亚洲熟妇中文字幕五十中出| 中文字幕日本人妻久久久免费| 午夜亚洲国产理论秋霞| 日韩在线播放全免费| 亚洲国产成人综合精品| 亚洲视频在线精品| 蜜桃成人无码区免费视频网站| 亚洲乱码卡一卡二卡三| 国产免费卡一卡三卡乱码| 中文在线观看免费网站| 亚洲精品欧洲精品| 色吊丝最新永久免费观看网站| 一级毛片a女人刺激视频免费| 亚洲处破女AV日韩精品| 久久精品a一国产成人免费网站 | 国产成人免费视频| 亚洲第一精品电影网| 香蕉视频在线观看免费国产婷婷| 一个人看www免费高清字幕| 亚洲日本在线观看| 可以免费观看一级毛片黄a| 久久久久久国产精品免费免费男同 | 337p日本欧洲亚洲大胆色噜噜| 四色在线精品免费观看| 天堂在线免费观看| 亚洲日本国产综合高清| 亚洲亚洲人成综合网络|