成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

JavaScript設(shè)計(jì)模式(八):組合模式

leon / 2052人閱讀

摘要:不同于其它靜態(tài)編程語(yǔ)言,實(shí)現(xiàn)組合模式的難點(diǎn)是保持樹對(duì)象與葉對(duì)象之間接口保持統(tǒng)一,可借助定制接口規(guī)范,實(shí)現(xiàn)類型約束。誤區(qū)規(guī)避組合不是繼承,樹葉對(duì)象并不是父子對(duì)象組合模式的樹型結(jié)構(gòu)是一種聚合的關(guān)系,而不是。

組合模式:又叫 “部分整體” 模式,將對(duì)象組合成樹形結(jié)構(gòu),以表示 “部分-整體” 的層次結(jié)構(gòu)。通過(guò)對(duì)象的多態(tài)性表現(xiàn),使得用戶對(duì)單個(gè)對(duì)象和組合對(duì)象的使用具有一致性。

生活小栗子:文件目錄,DOM 文檔樹

模式特點(diǎn)

表示 “部分-整體” 的層次結(jié)構(gòu),生成 "樹葉型" 結(jié)構(gòu);

一致操作性,樹葉對(duì)象對(duì)外接口保存一致(操作與數(shù)據(jù)結(jié)構(gòu)一致);

自上而下的的請(qǐng)求流向,從樹對(duì)象傳遞給葉對(duì)象;

調(diào)用頂層對(duì)象,會(huì)自行遍歷其下的葉對(duì)象執(zhí)行。

代碼實(shí)現(xiàn)

樹對(duì)象和葉對(duì)象接口統(tǒng)一,樹對(duì)象增加一個(gè)緩存數(shù)組,存儲(chǔ)葉對(duì)象。執(zhí)行樹對(duì)象方法時(shí),將請(qǐng)求傳遞給其下葉對(duì)象執(zhí)行。

// 樹對(duì)象 - 文件目錄
class CFolder {
    constructor(name) {
        this.name = name;
        this.files = [];
    }

    add(file) {
        this.files.push(file);
    }

    scan() {
        for (let file of this.files) {
            file.scan();
        }
    }
}

// 葉對(duì)象 - 文件
class CFile {
    constructor(name) {
        this.name = name;
    }

    add(file) {
        throw new Error("文件下面不能再添加文件");
    }

    scan() {
        console.log(`開始掃描文件:${this.name}`);
    }
}

let mediaFolder = new CFolder("娛樂(lè)");
let movieFolder = new CFolder("電影");
let musicFolder = new CFolder("音樂(lè)");

let file1 = new CFile("鋼鐵俠.mp4");
let file2 = new CFile("再談?dòng)洃?mp3");
movieFolder.add(file1);
musicFolder.add(file2);
mediaFolder.add(movieFolder);
mediaFolder.add(musicFolder);
mediaFolder.scan();

/* 輸出:
開始掃描文件:鋼鐵俠.mp4
開始掃描文件:再談?dòng)洃?mp3
*/

CFolderCFile 接口保持一致。執(zhí)行 scan() 時(shí),若發(fā)現(xiàn)是樹對(duì)象,則繼續(xù)遍歷其下的葉對(duì)象,執(zhí)行 scan()。

JavaScript 不同于其它靜態(tài)編程語(yǔ)言,實(shí)現(xiàn)組合模式的難點(diǎn)是保持樹對(duì)象與葉對(duì)象之間接口保持統(tǒng)一,可借助 TypeScript 定制接口規(guī)范,實(shí)現(xiàn)類型約束。

// 定義接口規(guī)范
interface Compose {
    name: string,
    add(file: CFile): void,
    scan(): void
}

// 樹對(duì)象 - 文件目錄
class CFolder implements Compose {
    fileList = [];
    name: string;

    constructor(name: string) {
        this.name = name;
    }

    add(file: CFile) {
        this.fileList.push(file);
    }

    scan() {
        for (let file of this.fileList) {
            file.scan();
        }
    }
}

// 葉對(duì)象 - 文件
class CFile implements Compose {
    name: string;

    constructor(name: string) {
        this.name = name;
    }

    add(file: CFile) {
        throw new Error("文件下面不能再添加文件");
    }

    scan() {
        console.log(`開始掃描:${this.name}`)
    }
}

let mediaFolder = new CFolder("娛樂(lè)");
let movieFolder = new CFolder("電影");
let musicFolder = new CFolder("音樂(lè)");

let file1 = new CFile("鋼鐵俠.mp4");
let file2 = new CFile("再談?dòng)洃?mp3");
movieFolder.add(file1);
musicFolder.add(file2);
mediaFolder.add(movieFolder);
mediaFolder.add(musicFolder);
mediaFolder.scan();

/* 輸出:
開始掃描文件:鋼鐵俠.mp4
開始掃描文件:再談?dòng)洃?mp3
*/
透明性的安全問(wèn)題

組合模式的透明性,指的是樹葉對(duì)象接口保持統(tǒng)一,外部調(diào)用時(shí)無(wú)需區(qū)分。但是這會(huì)帶來(lái)一些問(wèn)題,如上述文件目錄的例子,文件(葉對(duì)象)下不可再添加文件,因此需在文件類的 add() 方法中拋出異常,以作提醒。

誤區(qū)規(guī)避 1. 組合不是繼承,樹葉對(duì)象并不是父子對(duì)象

組合模式的樹型結(jié)構(gòu)是一種 HAS-A(聚合)的關(guān)系,而不是 IS-A 。樹葉對(duì)象能夠合作的關(guān)鍵,是它們對(duì)外保持統(tǒng)一接口,而不是葉對(duì)象繼承樹對(duì)象的屬性方法,兩者之間不是父子關(guān)系。

2. 葉對(duì)象操作保持一致性

葉對(duì)象除了與樹對(duì)象接口一致外,操作也必須保持一致性。一片葉子只能生在一顆樹上。調(diào)用頂層對(duì)象時(shí),每個(gè)葉對(duì)象只能接收一次請(qǐng)求,一個(gè)葉對(duì)象不能從屬多個(gè)樹對(duì)象。

3. 葉對(duì)象實(shí)現(xiàn)冒泡傳遞

請(qǐng)求傳遞由樹向葉傳遞,如果想逆轉(zhuǎn)傳遞過(guò)程,需在葉對(duì)象中保留對(duì)樹對(duì)象的引用,冒泡傳遞給樹對(duì)象處理。

4. 不只是簡(jiǎn)單的子集遍歷

調(diào)用對(duì)象的接口方法時(shí),如果該對(duì)象是樹對(duì)象,則會(huì)將請(qǐng)求傳遞給葉對(duì)象,由葉對(duì)象執(zhí)行方法,以此類推。不同于迭代器模式,迭代器模式遍歷并不會(huì)做請(qǐng)求傳導(dǎo)。

應(yīng)用場(chǎng)景

優(yōu)化處理遞歸或分級(jí)數(shù)據(jù)結(jié)構(gòu)(文件系統(tǒng) - 目錄文件管理);

與其它設(shè)計(jì)模式聯(lián)用,如與命令模式聯(lián)用實(shí)現(xiàn) “宏命令”。

優(yōu)缺點(diǎn)

優(yōu)點(diǎn):

忽略組合對(duì)象和單個(gè)對(duì)象的差別,對(duì)外一致接口使用;

解耦調(diào)用者與復(fù)雜元素之間的聯(lián)系,處理方式變得簡(jiǎn)單。

缺點(diǎn)

樹葉對(duì)象接口一致,無(wú)法區(qū)分,只有在運(yùn)行時(shí)方可辨別;

包裹對(duì)象創(chuàng)建太多,額外增加內(nèi)存負(fù)擔(dān)。

參考文章

《JavaScript 設(shè)計(jì)模式與開發(fā)實(shí)踐》

本文首發(fā)Github,期待Star!
https://github.com/ZengLingYong/blog

作者:以樂(lè)之名
本文原創(chuàng),有不當(dāng)?shù)牡胤綒g迎指出。轉(zhuǎn)載請(qǐng)指明出處。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/110270.html

相關(guān)文章

  • JavaScript常用種繼承方案

    摘要:原型式繼承利用一個(gè)空對(duì)象作為中介,將某個(gè)對(duì)象直接賦值給空對(duì)象構(gòu)造函數(shù)的原型。其中表示構(gòu)造函數(shù),一個(gè)類中只能有一個(gè)構(gòu)造函數(shù),有多個(gè)會(huì)報(bào)出錯(cuò)誤如果沒(méi)有顯式指定構(gòu)造方法,則會(huì)添加默認(rèn)的方法,使用例子如下。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo))showImg(https://segmentfault.com/img/rem...

    wpw 評(píng)論0 收藏0
  • PHP設(shè)計(jì)模式)橋接模式(Bridge For PHP)

    摘要:橋接設(shè)計(jì)模式橋接模式將兩個(gè)原本不相關(guān)的類結(jié)合在一起,然后利用兩個(gè)類中的方法和屬性,輸出一份新的結(jié)果。模擬企業(yè)分組發(fā)送短信需求公司現(xiàn)在需要按分組臨時(shí)工正式工管理層等以多種形式微博等給員工發(fā)送通知。 橋接設(shè)計(jì)模式 橋接模式:將兩個(gè)原本不相關(guān)的類結(jié)合在一起,然后利用兩個(gè)類中的方法和屬性,輸出一份新的結(jié)果。 案例 模擬毛筆 需求:現(xiàn)在需要準(zhǔn)備三種粗細(xì)(大中小),并且有五種顏色的比 如果使用蠟...

    K_B_Z 評(píng)論0 收藏0
  • JavaScript學(xué)習(xí)總結(jié)()正則表達(dá)式

    摘要:首先推薦幾個(gè)正則表達(dá)式編輯器正則表達(dá)式是一種查找以及字符串替換操作。此表所列的常用正則表達(dá)式,除個(gè)別外均未在前后加上任何限定,請(qǐng)根據(jù)需要,自行處理。例如對(duì)而言,則采用一對(duì)引號(hào)來(lái)確定正則表達(dá)式的邊界。 這篇文章本來(lái)很早就要寫的,拖了挺久的,現(xiàn)在整理下,供大家學(xué)習(xí)交流哈! 基本概念 正則表達(dá)式是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為元字符)。模式描述在搜...

    trilever 評(píng)論0 收藏0
  • Java設(shè)計(jì)模式之()——適配器模式

    摘要:適配器模式應(yīng)用場(chǎng)景適配器模式應(yīng)用場(chǎng)景修改已使用的接口某個(gè)已經(jīng)投產(chǎn)中的接口需要修改,這時(shí)候使用適配器最好。適配器模式適配器模式是一種事后的補(bǔ)救策略。1、什么是適配器模式?Convert the interface of a class into another interface clients expect.Adapter lets classes work together that co...

    番茄西紅柿 評(píng)論0 收藏2637
  • JavaScript系列--淺析原型鏈與繼承

    摘要:綜上所述有原型鏈繼承,構(gòu)造函數(shù)繼承經(jīng)典繼承,組合繼承,寄生繼承,寄生組合繼承五種方法,寄生組合式繼承,集寄生式繼承和組合繼承的優(yōu)點(diǎn)于一身是實(shí)現(xiàn)基于類型繼承的最有效方法。 一、前言 繼承是面向?qū)ο螅∣OP)語(yǔ)言中的一個(gè)最為人津津樂(lè)道的概念。許多面對(duì)對(duì)象(OOP)語(yǔ)言都支持兩種繼承方式::接口繼承 和 實(shí)現(xiàn)繼承 。 接口繼承只繼承方法簽名,而實(shí)現(xiàn)繼承則繼承實(shí)際的方法。由于js中方法沒(méi)有簽名...

    draveness 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<