組合模式
又稱部分整體-模式,將對象合成樹形結構以表示“部分整體”的層次結構。
簡單來說,就是將一個複雜的系統,拆分成功能相對獨立的個體,然後通過這些個體的組合形成一個新的整體。
舉例
這裏我們將一個新聞列表拆分出各個部分,通過一個組件樹來構建。
// 新聞抽象類
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();
在這裏我們利用組合模式,將每一層的每一個組件都變成一個獨立的類,構建整體的時候通過各個類的實例來進行構建。
通過拆出來每一個組件,我們將整體中的各個部分解耦,可以很方便的對已有的組件進行擴展,也可以很方便的改變已有的結構,通過組件的組合創建出新的結構。
總結
利用組合模式,我們將各部分獨立,通過將各部分進行組合,形成一個整體。
得到各部分解耦,整體便於擴展和調整的結構。