橋接模式:在系統(tǒng)沿著多個(gè)維度變化的同時(shí),又不增加其復(fù)雜度并已達(dá)到解耦。
有時(shí)候頁(yè)面中的一些小小的細(xì)節(jié)改變常常因邏輯相似導(dǎo)致大片臃腫的代碼,讓頁(yè)面苦澀不堪。
需求1:頁(yè)面上不的用戶信息部分添加一下鼠標(biāo)焦點(diǎn)特效。
對(duì)于用戶名,鼠標(biāo)劃過直接改變顏色,用戶等級(jí)、用戶信息這類不見改變里面數(shù)字的內(nèi)容。
const spans = docunemt.querySelectorAll('span');
//為用戶名綁定特效
spans[0].addEventListener('mouseover',function(){
this.style.color = 'red';
this.style.background = '#ddd';
})
spans[0].addEventListener('mouseout',function(){
this.style.color = '333';
this.style.background = '#f5f5f5';
})
//為等級(jí)綁定特效
spans[1].addEventListener('mouseover',function(){
this.querySelectorAll('strong')[0].styles.color='red';
this.querySelectorAll('strong')[0].styles.background='#ddd';
})
spans[1].addEventListener('mouseout',function(){
this.querySelectorAll('strong')[0].styles.color='#333';
this.querySelectorAll('strong')[0].styles.background='#f5f5f5';
})
問題1:由于處理邏輯不同,所以寫了不少代碼,寫完后發(fā)現(xiàn)很多代碼是冗余的。
優(yōu)化1:對(duì)相同邏輯做抽象處理,使代碼簡(jiǎn)潔,重復(fù)率更大,可讀性更高
//抽象
function changeColor(dom,color,bg){
//設(shè)置元素的字體顏色
dom.style.color = color;
//設(shè)置元素的背景顏色
dom.style.background = bg
}
僅僅知道元素事件綁定與抽象提取的設(shè)置樣式方法changeColor還是不夠,需要用一個(gè)方法將他們連接起來,這個(gè)方法(下面的綁定事件的匿名方法)可以稱為橋接方法,這種模式就是橋接模式。
const spans = docunemt.querySelectorAll('span')
spans[0].addEventListener('mouseover',function(){
changeColor(this,'res','#ddd');
})
spans[0].addEventListener('mouseout',function(){
changeColor(this,'333','#f5f5f5');
})
上面的橋接模式可以理解為:先抽取共用部分,然后將實(shí)現(xiàn)與抽象通過橋接方法連接在一起,來實(shí)現(xiàn)解耦的作用.
多元化對(duì)象
橋接模式的強(qiáng)大不僅僅在此,甚至對(duì)于多維的變化也同樣適用。
e.g.
書寫一個(gè)canvas跑步游戲。
對(duì)于游戲中的人、小精靈、小球等一系列的實(shí)物都有動(dòng)作單元,而他們的每個(gè)動(dòng)作實(shí)現(xiàn)起來方式又是統(tǒng)一的,
比如人和精靈和球的運(yùn)動(dòng)就是位置坐標(biāo)x和y的變化,
球的顏色和精靈的色彩的繪制方式都相似,
可以將這些多維變化部分,通過提取出來作為每一個(gè)抽象運(yùn)動(dòng)單元進(jìn)行保存,
當(dāng)創(chuàng)建實(shí)體時(shí),將需要的每個(gè)抽象動(dòng)作單元通過橋接,連接在一起。
這樣他們之間不會(huì)相互影響并且改方式降低了他們之間的耦合。
//多元變量類
//運(yùn)動(dòng)單元
function Speed(x,y){
this.x = x;
this.y = y;
}
Speed.prototype.run = function(){
console.log('運(yùn)動(dòng)起來');
}
// 著色單元
function Color(cl){
this.color = cl
}
Color.prototype.draw = function(){
console.log('繪制顏色')
}
// 變形單元
function Shape(sp){
this.shape = sp
}
Color.prototype.change = function(){
console.log('改變形狀')
}
// 說話單元
function Speek(wd){
this.word = wd
}
Color.prototype.say = function(){
console.log('書寫字體')
}
/*創(chuàng)建一個(gè)球類,并且它可以運(yùn)動(dòng),可以著色*/
function Ball(x,y,c){
//實(shí)現(xiàn)運(yùn)動(dòng)單元
this.speed = new Speed(x,y)
//實(shí)現(xiàn)著色單元
this.color = new Color(c)
}
Ball.prototype.init = function(){
//實(shí)現(xiàn)運(yùn)動(dòng)
this.speed.run()
//實(shí)現(xiàn)著色
this.color.draw()
}
/*創(chuàng)建一個(gè)人物類,他可以運(yùn)動(dòng)以及說話*/
function People(x,y,f){
this.speed = new Speed(x,y);
this.font = new Speek(f);
}
People.prototype.init = function(){
this,speed.run();
this.font.say();
}
/*創(chuàng)建一個(gè)精靈類,讓它可以運(yùn)動(dòng)可以著色可以改變形狀*/
function Spirite(x,y,c,s){
this.speed = new Speed(x,y);
this.color = new Color(c);
this.shape = new Shape(c);
}
Spirite.prototype.init = function(){
this.speed.run();
this.color.draw();
this.shape.change();
}
當(dāng)我們想實(shí)現(xiàn)一個(gè)人物時(shí),我們直接實(shí)例化一個(gè)人物對(duì)象,這樣他就可以有運(yùn)動(dòng)和說話的動(dòng)作了
const p = new People(10,12,16);
p.init();
橋接模式主要是對(duì)結(jié)構(gòu)之間的解構(gòu),而抽象工廠模式與創(chuàng)建者模式主要業(yè)務(wù)在于創(chuàng)建。
通過僑聯(lián)模式,使實(shí)現(xiàn)層與抽象層分開處理,避免需求的改變?cè)斐蓪?duì)象內(nèi)部的修改,
體現(xiàn)了面向?qū)ο髮?duì)擴(kuò)展的開放及對(duì)修改的關(guān)閉原則。