组合模式
又称部分整体-模式,将对象合成树形结构以表示“部分整体”的层次结构。
简单来说,就是将一个复杂的系统,拆分成功能相对独立的个体,然后通过这些个体的组合形成一个新的整体。
举例
这里我们将一个新闻列表拆分出各个部分,通过一个组件树来构建。
// 新闻抽象类
class News {
constructor() {
this.children = [];
this.element = null;
}
init() {
throw new Error('请重写你的方法');
}
add(){
throw new Error('请重写你的方法');
}
getElement(){
throw new Error('请重写你的方法');
}
}
// 总容器
class Container extends News {
constructor(id,parent){
super();
this.id = id;
this.parent = parent;
this.init();
}
init() {
this.element = document.createElement('ul');
this.element.id = this.id;
this.element.className = 'new-container';
}
add(child){
this.children.push(child);
this.element.appdendChild(child.getElement());
return this;
}
getElement(){
return this.element;
}
}
// 每条item的容器
class Item extends News {
constructor(className){
this.className = className || '';
this.init()'
}
init() {
this.element = docuemnt.createElement('li');
this.element.className = this.className;
}
add(child){
this.children.push(child);
this.element.appendChild(child.getElement());
return this;
}
getElement(){
return this.getElement();
}
}
// 每个新闻组的容器
class NewsGroup extends News {
constructor(className){
super();
this.className = className;
this.init();
}
init(){
this.element = document.createElement('div');
this.element.className = this.className;
}
add(child){
this.children.push(child);
this.element.appdendChild(child.getElement());
return this;
}
getElement(){
return this.element;
}
}
上面的一个抽象类和三个实现了这个抽象类的子类都是新闻的容器。接下来给出具体的新闻类。
class ImageNews extends News {
concstructor(url,href,className){
this.url = url || '';
this.href = href || '#';
this.className = className || 'normal';
this.init();
}
init() {
this.element = document.createElement('a');
this.element.href = this.href;
let img = new Image();
img.src = this.url;
this.element.appendChild(img);
this.element.className = 'image-news '+this.className;
}
getElement(){
return this.element;
}
}
class IconNews extends News {
constructor(text,href,type){
super();
this.text = text || '';
this.href = href || '#';
this.type = type || ;
this.init();
}
init() {
this.element = document.createElement('a');
this.element.href = this.href;
this.element.innerHTML = this.text;
this.element.className = 'icon '+this.type;
}
getElement(){
return this.element;
}
}
class EasyNews extends News {
constructor(text,href) {
super();
this.href = href;
this.text = text;
this.init();
}
init(){
this.element = document.createElement('a');
this.element.innerHTML = this.text;
this.element.href = this.href;
this.element.className = 'text';
}
getElement() {
return this.element;
}
}
class TypeNews extends News {
constructor(text,href,type,pos) {
super();
this.text = text || '';
this.href = href || '#';
this.type = type || '';
this.pos = pos || 'left';
this.init();
}
init() {
this.element = document.createElement('a');
if(this.pos == 'left')
this.element.innerHTML = `[${this.type}]`+this.text;
else
this.element.innerHTML = this.text + `[${this.type}]`;
this.element.href = this.href;
this.element.className = 'text';
}
getElement() {
return this.element;
}
}
下面是使用的代码:
// 下面是使用
let news = new Container('news', document.body)
news.add(
new Item().add(
new IconNews('梅西不能金球也伟大')
)
).add(
new Item().add(
new IconNews('保护强国强队用意明显','#','live')
)
).add(
new Item().add(
new NewsGroup('has-image').add(
new ImageNews('img/1.jpg','#','small')
).add(
new EasyNews('从240斤胖子成功变成型男')
).add(
new EasyNews('五大雷人跑步机')
)
)
).add(
new Item().add(
new TypeNews('AK47不愿意为费城打球', '#', 'NBA','left')
)
).add(
new Item().add(
new TypeNews('火炮彪6三分创新高','#','CBA','right')
)
).show();
在这里我们利用组合模式,将每一层的每一个组件都变成一个独立的类,构建整体的时候通过各个类的实例来进行构建。
通过拆出来每一个组件,我们将整体中的各个部分解耦,可以很方便的对已有的组件进行扩展,也可以很方便的改变已有的结构,通过组件的组合创建出新的结构。
总结
利用组合模式,我们将各部分独立,通过将各部分进行组合,形成一个整体。
得到各部分解耦,整体便于扩展和调整的结构。