组合模式-> 又称部分模式
将对象和恒树行结构以表示部分-整体的层次结构
使用者可以使用统一的方式对待组合对象和叶子对象
优点
- 高层模块化调用简单
- 节点自由增加
缺点
- 在使用组合模式是,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置
使用场景
部分,整体场景, 如树形菜单。文件,文件夹。
实现
- 虚拟dom案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>虚拟DOM</title>
</head>
<body>
<div id="app"></div>
<script>
// 虚拟node
class ELem {
constructor(type, props) {
this.type = type
this.props = props
}
}
const React = {
// 创建虚拟node
createElem(type, props, ...childs) {
return new ELem(type, {...props, children:childs})
},
/**
* @desc 渲染函数
*/
render(el, container) {
// 拿到属性值 进行处理
let { props } = el
let keys = Object.keys(props)
// 创建dom节点
let node = document.createElement(el.type)
// 遍历 处理属性
keys.forEach(key => {
// 处理子节点
if (key === 'children') {
props[key].forEach(child => {
if (typeof child === 'string') {
// 文本节点直接创建
node.appendChild(document.createTextNode(child))
} else {
// 遍历渲染node
React.render(child, node)
}
})
} else if (key == 'className') {
node.setAttribute('class', props[key]);
} else {
node.setAttribute(key , props[key]);
}
})
container.appendChild(node)
}
}
// ReactDOM.render(<div>hello<span>world</span></div>);
let app = document.querySelector('#app')
let els = React.createElem(
"div",
null,
"hello,",
React.createElem("span",null,"world!" )
)
React.render(els, app)
</script>
</body>
</html>
- 计算器
function Folder(name) {
this.name=name;
this.children=[];
this.parent=null;
this.level=0;
}
Folder.prototype.add=function (child) {
child.level=this.level+1;
child.parent=this;
this.children.push(child);
}
Folder.prototype.show=function () {
console.log(' '.repeat(this.level)+'文件夹'+this.name);
for (let i=0;i<this.children.length;i++){
this.children[i].show();
}
}
Folder.prototype.remove=function () {
if (!this.parent) return;
for (let i=0;i<this.parent.children.length;i++){
let current=this.parent.children[i];
if (current === this) {
return this.parent.children.splice(i,1);
}
}
}
function File(name) {
this.name=name;
}
File.prototype.add=function () {
throw new Error(`文件下面不能再添加文件`);
}
File.prototype.show=function () {
console.log(' '.repeat(this.level)+'文件'+this.name);
}
let folder=new Folder('视频');
let liveFolder=new Folder('生活视频');
let moveFolder=new Folder('电影剪辑视频');
let liveFile=new File('心情记录');
let workFile=new File('工作记录');
folder.add(liveFolder);
folder.add(moveFolder);
liveFolder.add(liveFile);
moveFolder.add(workFile);
folder.show();
liveFolder.remove();
folder.show();