组合模式:
组合模式是用小的子对象来构建更大的对象,而这些小的子对象本身也许是由更小的对象构成的。父对象和子对象拥有共同的对象接口,而他们可以组合在一起组成一个更强大的数据结构。一般由子对象进行处理,如果传递到还是非子对象,则继续往下传递直到子对象为止。
类似于命令模式将事件包装成有统一接口的模式,而组合模式就是父对象和子对象就是有相同的对外接口,这里的父对象和子对象并不是父子关系,只是包含组合关系。
比如一个页面上有个button,点击后先开始了loading动画,然后弹框显示提示,最后跳转到别的网站,这3组动作,让我们用组合模式实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| var loading = { add() { throw new Error('child can not be added'); } run() { console.log('show loading'); } };
var dialog = { add() { throw new Error('child can not be added'); } run() { console.log('show dialog'); } };
var link = { add() { throw new Error('child can not be added'); } run() { console.log('redirect link'); } };
var macroCommand = { cmdLists: [], add(cmd) { this.cmdLists.push(cmd); }, run() { for(var i = 0; i < this.cmdLists.length; i++) { this.cmdLists[i].run(); } } };
macroCommand.add(loading); macroCommand.add(dialog); macroCommand.add(link);
document.getElementById('btn').onclick = macroCommand.run;
|
当点击按钮以后会依次显示show loading
, show dialog
,redirect link
,上述代码中,loading, dialog, link对象即是子对象,macroCommand即是父对象,他们都拥有相同的方法run,add,对于外界来说调用他们的方式是一样的。
可以看出组合模式的好处有对于未来有新增的子对象时,遍历的操作还是一样的,同时避免了打破主方法的封闭-开放原则。