组合对象,包括部件对象和叶对象.叶对象相当于最小粒度,不可再划分;而部件对象也是组合对象,是由叶对象组合而成.小的组合对象再经过不断组合,就成为一个大的组合对象;大的组合对象再次组装,就是一个整体.代码通过组合模式组合起来之后,具体执行请求时,是从上而下沿着树形结构进行传递的,一直传递到不可划分的叶子节点对象.
栗子:
创建一个表单.要求点提交按钮,可以保存和验证各项的值.这个表单的元素有多少项并不知道,也不知道具体是什么内容,是注册表单验证还是登陆表单验证?根据用户的需求而异,也就是实现一个动态表单.这时,组合模式就派上用场了,如下图:
将动态form看成一个整体,然后根据粒度划分出最小叶子节点.根据上图和我们dom节点类型,我们可以将input,select,textarea三种类型的节点看做叶子对象.划分出最小叶子对象后,就可以根据实际场景,划分出由叶子对象组合成的部件对象,部件对象再经过随意无限次组合,可以成为最终的满足某一需求的form表单,非常灵活.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>组合模式</title>
<head>
<body>
</body>
</html>
<script type="text/javascript">
var CompositeForm = function(id) {
this.formComponents = [];
this.formElement = document.createElement('form');
this.formElement.id = id;
this.formElement.onsubmit = function() {
return false;
}
}
CompositeForm.prototype.add = function(child) {
this.formComponents.push(child);
}
CompositeForm.prototype.loadElements = function() {
for(var i=0; i<this.formComponents.length; i++) {
this.formElement.appendChild(this.formComponents[i].divElement);
}
var submitButton = document.createElement('input');
submitButton.id = 'sub';
submitButton.type = 'submit';
this.formElement.appendChild(submitButton);
}
CompositeForm.prototype.save = function() {
for(var i=0; i<this.formComponents.length; i++) {
this.formComponents[i].save();
}
}
var InputField = function(label, id, type) {
//创建input节点
this.input = document.createElement('input');
this.input.id = id;
this.input.type = type;
//创建文本节点
this.label = document.createElement('label');
var labelTextNode = document.createTextNode(label);
this.label.appendChild(labelTextNode);
//创建div节点
this.divElement = document.createElement('div');
this.divElement.className = 'input-field';
this.divElement.appendChild(this.label);
this.divElement.appendChild(this.input);
}
InputField.prototype.save = function() {
var value = this.input.value;
sessionStorage.setItem(this.input.id, value);
console.log(sessionStorage.getItem(this.input.id));
}
var form = new CompositeForm('myform');
//开始组合
form.add(new InputField('用户名', 'userName', 'text'));
form.add(new InputField('密码', 'password', 'password'));
form.add(new InputField('邮箱', 'email', 'text'));
//装填所有节点
form.loadElements();
//append到body
document.body.appendChild(form.formElement);
//试验一下
document.getElementById('sub').onclick = function() {
form.save();
}
</script>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。