JavaScript組合模式Composite Pattern
組合模式(Composite Pattern
),又叫部分整體模式,是用于把一組相似的對(duì)象當(dāng)作一個(gè)單一的對(duì)象。
組合模式依據(jù)樹(shù)形結(jié)構(gòu)來(lái)組合對(duì)象,用來(lái)表示部分以及整體層次。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式,它創(chuàng)建了對(duì)象組的樹(shù)形結(jié)構(gòu)。
樹(shù)對(duì)象和葉對(duì)象接口統(tǒng)一,樹(shù)對(duì)象增加一個(gè)緩存數(shù)組,存儲(chǔ)葉對(duì)象。執(zhí)行樹(shù)對(duì)象方法時(shí),將請(qǐng)求傳遞給其下葉對(duì)象執(zhí)行。
// 樹(shù)對(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(`開(kāi)始掃描文件:${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();
輸出:
開(kāi)始掃描文件:鋼鐵俠.mp4
開(kāi)始掃描文件:再談?dòng)洃?mp3
??CFolder?
?與 ??CFile?
? 接口保持一致。執(zhí)行 ??scan()?
? 時(shí),若發(fā)現(xiàn)是樹(shù)對(duì)象,則繼續(xù)遍歷其下的葉對(duì)象,執(zhí)行 ??scan()?
?。
JavaScript 不同于其它靜態(tài)編程語(yǔ)言,實(shí)現(xiàn)組合模式的難點(diǎn)是保持樹(shù)對(duì)象與葉對(duì)象之間接口保持統(tǒng)一,可借助 TypeScript 定制接口規(guī)范,實(shí)現(xiàn)類型約束。
// 定義接口規(guī)范 interface Compose { name: string, add(file: CFile): void, scan(): void } // 樹(shù)對(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(`開(kāi)始掃描:${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();
輸出:
開(kāi)始掃描文件:鋼鐵俠.mp4
開(kāi)始掃描文件:再談?dòng)洃?mp3
需要注意的是:
- 組合不是繼承,樹(shù)葉對(duì)象并不是父子對(duì)象
- 葉對(duì)象操作保持一致性
- 葉對(duì)象實(shí)現(xiàn)冒泡傳遞
- 不只是簡(jiǎn)單的子集遍歷
它的應(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):忽略組合對(duì)象和單個(gè)對(duì)象的差別,對(duì)外一致接口使用;解耦調(diào)用者與復(fù)雜元素之間的聯(lián)系,處理方式變得簡(jiǎn)單。
它的缺點(diǎn):樹(shù)葉對(duì)象接口一致,無(wú)法區(qū)分,只有在運(yùn)行時(shí)方可辨別;包裹對(duì)象創(chuàng)建太多,額外增加內(nèi)存負(fù)擔(dān)。
到此這篇關(guān)于學(xué)習(xí)理解JavaScript組合模式Composite Pattern的文章就介紹到這了,更多相關(guān)JS組合模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- JavaScript編程設(shè)計(jì)模式之觀察者模式(Observer Pattern)實(shí)例詳解
- JavaScript設(shè)計(jì)模式學(xué)習(xí)之適配器模式
- javascript設(shè)計(jì)模式 – 適配器模式原理與應(yīng)用實(shí)例分析
- JavaScript適配器模式原理與用法實(shí)例詳解
- JavaScript適配器模式詳解
- NodeJS設(shè)計(jì)模式總結(jié)【單例模式,適配器模式,裝飾模式,觀察者模式】
- javascript設(shè)計(jì)模式之Adapter模式【適配器模式】實(shí)現(xiàn)方法示例
- 理解JavaScript中的適配器模式Adapter?Pattern
相關(guān)文章
JavaScript中將一個(gè)值轉(zhuǎn)換為字符串的方法分析[譯]
在JavaScript中,主要有三種方法能讓任意值轉(zhuǎn)換為字符串.本文講解了每種方法以及各自的優(yōu)缺點(diǎn)2012-09-09document.write()及其輸出內(nèi)容的樣式、位置控制
document.write(),用于簡(jiǎn)單的打印內(nèi)容到頁(yè)面上,可以逐字打印你需要的內(nèi)容,既然可以輸出變量,肯定會(huì)想要去控制下變量的顯示,比如位置以及樣式2013-08-08JS跨域解決方案之使用CORS實(shí)現(xiàn)跨域
正常使用AJAX會(huì)需要正常考慮跨域問(wèn)題,所以偉大的程序員們又折騰出了一系列跨域問(wèn)題的解決方案,如JSONP、flash、ifame、xhr2等等。本文給大家介紹JS跨域解決方案之使用CORS實(shí)現(xiàn)跨域,感興趣的朋友參考下吧2016-04-04微信小程序?qū)崿F(xiàn)選項(xiàng)卡滑動(dòng)切換
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)選項(xiàng)卡滑動(dòng)切換,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-10-10JavaScript中Number.isNaN 和 isNaN 的區(qū)別詳解
本文和大家分享一個(gè)前幾天寫(xiě)代碼踩的坑,筆者在業(yè)務(wù)邏輯中需要對(duì)一個(gè)值進(jìn)行NaN的判斷,由于筆者的不嚴(yán)謹(jǐn),使用了isNaN,從而引起B(yǎng)ug,也正是因?yàn)檫@個(gè),筆者才知道了isNaN和Number.isNaN的區(qū)別,所以本文就和大家聊聊它們的區(qū)別2023-09-09