組合模式如果運(yùn)用得當(dāng)邑彪,可以大大簡(jiǎn)化客戶的代碼。一般來(lái)說(shuō)骤宣,組合模式適用于以下這兩種情況秦爆。
- 表示對(duì)象的部分-整體層次結(jié)構(gòu)。組合模式可以方便的構(gòu)造一棵樹(shù)來(lái)表示對(duì)象的部分-整體結(jié)果憔披。特別是我們?cè)陂_(kāi)發(fā)期間不確定這棵樹(shù)到底存在多少層次的時(shí)候等限。在樹(shù)的構(gòu)造最終完成之后爸吮,只需要通過(guò)請(qǐng)求樹(shù)的最頂層對(duì)象,便能對(duì)整棵樹(shù)做同一的操作望门。在組合模式中增加和刪除樹(shù)的節(jié)點(diǎn)非常方便形娇,并且符合開(kāi)放-封閉原則。
- 客戶希望統(tǒng)一對(duì)待樹(shù)中的所有對(duì)象筹误。組合模式使客戶可以忽略組合對(duì)象和葉對(duì)象的區(qū)別桐早,客戶在面對(duì)這棵樹(shù)的時(shí)候,不用關(guān)心當(dāng)前正在處理的是組合對(duì)象還是葉對(duì)象厨剪,也就不用寫(xiě)一堆
if
哄酝、else
語(yǔ)句來(lái)分別處理它們。組合對(duì)象和葉對(duì)象會(huì)各自做自己正確的事情祷膳,這是組合模式最重要的能力陶衅。
下面用組合模式實(shí)現(xiàn)文件夾的操作,包括文件夾的添加文件直晨,刪除文件搀军,掃描文件操作。
const Folder = function (name) {
this.name = name
this.parent = null
this.files = []
}
Folder.prototype.add = function (file) {
file.parent = this
this.files.push(file)
}
Folder.prototype.scan = function () {
console.log('開(kāi)始掃描文件夾: ' + this.name)
for (let i = 0, file, files = this.files; file = files[i++];) {
file.scan()
}
}
Folder.prototype.remove = function () {
if (!this.parent) {
return
}
for (let files = this.parent.files, len = files.length - 1; len >= 0; len--) {
let file = files[len]
if (file === this) {
files.splice(len, 1)
}
}
}
const File = function (name) {
this.name = name
this.parent = null
}
File.prototype.add = function () {
throw new Error('文件下面不能再添加文件')
}
File.prototype.remove = function () {
if (!this.parent) {
return
}
for (let files = this.parent.files, len = files.length - 1; len >= 0; len--) {
let file = files[len]
if (file === this) {
files.splice(len, 1)
}
}
}
File.prototype.scan = function () {
console.log('開(kāi)始掃描文件: ' + this.name)
}
let folder = new Folder('學(xué)習(xí)資料')
let folder1 = new Folder('JavaScript')
let folder2 = new Folder('jQuery')
let file1 = new File('JavaScript設(shè)計(jì)模式與開(kāi)始實(shí)踐')
let file2 = new File('精通jQuery')
let file3 = new File('重構(gòu)與模式')
folder1.add(file1)
folder2.add(file2)
folder.add(folder1)
folder.add(folder2)
folder.add(file3)
folder.scan()
folder1.remove()
folder.scan()
但是勇皇,組合模式并不是完美的罩句,他可能會(huì)產(chǎn)生一個(gè)這樣的系統(tǒng):系統(tǒng)中每個(gè)對(duì)象看起來(lái)都與其他對(duì)象差不多。它們的區(qū)別只有在運(yùn)行的時(shí)候才會(huì)顯現(xiàn)出來(lái)儒士,這會(huì)使代碼難以理解的止。此外,如果通過(guò)組合模式創(chuàng)建了太多的對(duì)象着撩,那么這些對(duì)象可能會(huì)讓系統(tǒng)擔(dān)負(fù)不起。