自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

面試官:說說你對組合模式的理解?應(yīng)用場景?

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

一、是什么

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

如下面的代碼:

  1. var closeDoorCommand = { 
  2.   executefunction () { 
  3.     console.log('關(guān)門'); 
  4.   } 
  5. }; 
  6. var openPcCommand = { 
  7.   executefunction () { 
  8.     console.log('開電腦'); 
  9.   } 
  10. }; 
  11. var openQQCommand = { 
  12.   executefunction () { 
  13.     console.log('登錄 QQ'); 
  14.   } 
  15. }; 
  16.  
  17. var MacroCommand = function () { 
  18.   return { 
  19.     commandsList: [], 
  20.     addfunction (command) { 
  21.       this.commandsList.push(command); 
  22.     }, 
  23.     executefunction () { 
  24.       for (var i = 0, command; command = this.commandsList[i++];) { 
  25.         command.execute(); 
  26.       } 
  27.     } 
  28.   } 
  29. }; 
  30.  
  31. var macroCommand = MacroCommand(); 
  32. macroCommand.add(closeDoorCommand); 
  33. macroCommand.add(openPcCommand); 
  34. macroCommand.add(openQQCommand); 
  35. macroCommand.execute(); 

上述是命令模式的一個(gè)應(yīng)用,macroCommand命令叫做組合對象,其包含了closeDoorCommand、openPcCommand、openQQCommand三個(gè)葉對象

macroCommand 的 execute 方法里,并不執(zhí)行真正的操作,而是遍歷它所包含的葉對象,把真正的 execute 請求委托給這些葉對象

二、應(yīng)用場景

組合模式應(yīng)樹形結(jié)構(gòu)而生,所以組合模式的使用場景就是出現(xiàn)樹形結(jié)構(gòu)的地方:

  • 「命令分發(fā):」 只需要通過請求樹的最頂層對象,便能對整棵樹做統(tǒng)一的操作。在組合模式中增加和刪除樹的節(jié)點(diǎn)非常方便,并且符合開放-封閉原則;
  • 「統(tǒng)一處理:」 統(tǒng)一對待樹中的所有對象,忽略組合對象和葉對象的區(qū)別

如將上述例子稍復(fù)雜,當(dāng)我們點(diǎn)擊按鈕時(shí),出發(fā)一系列操作(打開空調(diào),打開電視,打開音響)其中打開電視和打開音響是一組組合對象,如下代碼:

  1. <button id=button>按我</button> 
  2. <script> 
  3.   var MacroCommand = function () { 
  4.     return { 
  5.       commandsList: [], 
  6.       addfunction (command) { 
  7.         this.commandsList.push(command); 
  8.       }, 
  9.       executefunction () { 
  10.         for (var i = 0, command; command = this.commandsList[i++];) { 
  11.           command.execute(); 
  12.         } 
  13.       } 
  14.     } 
  15.   }; 
  16.  
  17.   var openAcCommend = { 
  18.     executefunction () { 
  19.       console.log('打開空調(diào)'); 
  20.     } 
  21.   } 
  22.  
  23.   // 電視和音響一起打開 
  24.   var openTvCommand = { 
  25.     executefunction () { 
  26.       console.log('打開電視'); 
  27.     } 
  28.   } 
  29.   var openSoundCommand = { 
  30.     executefunction () { 
  31.       console.log('打開音響'); 
  32.     } 
  33.   } 
  34.   var macroCommand1 = MacroCommand() 
  35.   macroCommand1.add(openTvCommand) 
  36.   macroCommand1.add(openSoundCommand) 
  37.  
  38.   // 關(guān)門、開電腦、登QQ的命令 
  39.   var closeDoorCommand = { 
  40.     executefunction () { 
  41.       console.log('關(guān)門'); 
  42.     } 
  43.   }; 
  44.   var openPcCommand = { 
  45.     executefunction () { 
  46.       console.log('開電腦'); 
  47.     } 
  48.   }; 
  49.   var openQQCommand = { 
  50.     executefunction () { 
  51.       console.log('登錄 QQ'); 
  52.     } 
  53.   }; 
  54.   var macroCommand2 = MacroCommand(); 
  55.   macroCommand2.add(closeDoorCommand); 
  56.   macroCommand2.add(openPcCommand); 
  57.   macroCommand2.add(openQQCommand); 
  58.  
  59.   // 所有命令組合成一個(gè)超級命令 
  60.   var macroCommand = MacroCommand(); 
  61.   macroCommand.add(openAcCommend) 
  62.   macroCommand.add(macroCommand1) 
  63.   macroCommand.add(macroCommand2) 
  64.  
  65.   // 給超級遙控器綁定命令 
  66.   var setCommand = (function (command) { 
  67.     document.getElementById('button').onclick = function () { 
  68.       command.execute() 
  69.     } 
  70.   })(macroCommand) 
  71. </script> 

 

組合模式的透明性使得發(fā)起請求的客戶不用去顧忌樹中組合對象和葉對象的區(qū)別,但它們在本質(zhì)上是有區(qū)別的。

組合對象可以擁有葉子節(jié)點(diǎn),葉對象下面就沒有子節(jié)點(diǎn),所以我們可能會有一些誤操作,比如試圖往葉對象中添加子節(jié)點(diǎn)

解決方案就是給葉對象也增加 add 方法,并且在調(diào)用這個(gè)方法時(shí),拋出一個(gè)異常來及時(shí)提醒用戶,如下:

  1. var MacroCommand = function () { 
  2.   return { 
  3.     commandsList: [], 
  4.     addfunction (command) { 
  5.       this.commandsList.push(command); 
  6.     }, 
  7.     executefunction () { 
  8.       for (var i = 0, command; command = this.commandsList[i++];) { 
  9.         command.execute(); 
  10.       } 
  11.     } 
  12.   } 
  13. }; 
  14.  
  15. var openAcCommend = { 
  16.   executefunction () { 
  17.     console.log('打開空調(diào)'); 
  18.   }, 
  19.   addfunction() { 
  20.     throw new Error('葉對象不能添加子節(jié)點(diǎn)'
  21.   } 

三、總結(jié)

組合模式常使用樹形方式創(chuàng)建對象,如下圖:

特點(diǎn)如下:

  • 表示 “部分-整體” 的層次結(jié)構(gòu),生成 "樹葉型" 結(jié)構(gòu)
  • 一致操作性,樹葉對象對外接口保存一致(操作與數(shù)據(jù)結(jié)構(gòu)一致)
  • 自上而下的的請求流向,從樹對象傳遞給葉對象
  • 調(diào)用頂層對象,會自行遍歷其下的葉對象執(zhí)行

參考文獻(xiàn)

https://www.runoob.com/design-pattern/composite-pattern.html

https://segmentfault.com/a/1190000019773556

 

https://juejin.cn/post/6995851145490989070

 

責(zé)任編輯:武曉燕 來源: JS每日一題
相關(guān)推薦

2021-11-09 08:51:13

模式命令面試

2021-11-05 07:47:56

代理模式對象

2021-11-03 14:10:28

工廠模式場景

2021-11-11 16:37:05

模板模式方法

2021-11-22 23:50:59

責(zé)任鏈模式場景

2021-09-16 07:52:18

算法應(yīng)用場景

2021-08-16 08:33:26

git

2021-11-04 06:58:32

策略模式面試

2021-09-06 10:51:27

TypeScriptJavaScript

2021-09-28 07:12:09

測試路徑

2021-09-29 07:24:20

場景數(shù)據(jù)

2021-09-10 06:50:03

TypeScript裝飾器應(yīng)用

2021-10-08 09:59:32

冒泡排序場景

2021-10-13 18:01:33

快速排序場景

2021-09-08 07:49:34

TypeScript 泛型場景

2021-10-09 10:25:41

排序應(yīng)用場景

2021-05-31 10:35:34

TCPWebSocket協(xié)議

2021-06-01 08:25:06

Node.jsJavaScript運(yùn)行

2021-10-18 07:51:39

回溯算法面試

2021-10-11 09:38:41

開源
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號