桥接模式
2019-06-26 本文已影响0人
helloyoucan
桥接模式:在系统沿着多个维度变化的同时,又不增加其复杂度并已达到解耦。
有时候页面中的一些小小的细节改变常常因逻辑相似导致大片臃肿的代码,让页面苦涩不堪。
需求1:页面上不的用户信息部分添加一下鼠标焦点特效。
对于用户名,鼠标划过直接改变颜色,用户等级、用户信息这类不见改变里面数字的内容。
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';
})
//为等级绑定特效
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:由于处理逻辑不同,所以写了不少代码,写完后发现很多代码是冗余的。
优化1:对相同逻辑做抽象处理,使代码简洁,重复率更大,可读性更高
//抽象
function changeColor(dom,color,bg){
//设置元素的字体颜色
dom.style.color = color;
//设置元素的背景颜色
dom.style.background = bg
}
仅仅知道元素事件绑定与抽象提取的设置样式方法changeColor还是不够,需要用一个方法将他们连接起来,这个方法(下面的绑定事件的匿名方法)可以称为桥接方法,这种模式就是桥接模式。
const spans = docunemt.querySelectorAll('span')
spans[0].addEventListener('mouseover',function(){
changeColor(this,'res','#ddd');
})
spans[0].addEventListener('mouseout',function(){
changeColor(this,'333','#f5f5f5');
})
上面的桥接模式可以理解为:先抽取共用部分,然后将实现与抽象通过桥接方法连接在一起,来实现解耦的作用.
多元化对象
桥接模式的强大不仅仅在此,甚至对于多维的变化也同样适用。
e.g.
书写一个canvas跑步游戏。
对于游戏中的人、小精灵、小球等一系列的实物都有动作单元,而他们的每个动作实现起来方式又是统一的,
比如人和精灵和球的运动就是位置坐标x和y的变化,
球的颜色和精灵的色彩的绘制方式都相似,
可以将这些多维变化部分,通过提取出来作为每一个抽象运动单元进行保存,
当创建实体时,将需要的每个抽象动作单元通过桥接,连接在一起。
这样他们之间不会相互影响并且改方式降低了他们之间的耦合。
//多元变量类
//运动单元
function Speed(x,y){
this.x = x;
this.y = y;
}
Speed.prototype.run = function(){
console.log('运动起来');
}
// 着色单元
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('书写字体')
}
/*创建一个球类,并且它可以运动,可以着色*/
function Ball(x,y,c){
//实现运动单元
this.speed = new Speed(x,y)
//实现着色单元
this.color = new Color(c)
}
Ball.prototype.init = function(){
//实现运动
this.speed.run()
//实现着色
this.color.draw()
}
/*创建一个人物类,他可以运动以及说话*/
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();
}
/*创建一个精灵类,让它可以运动可以着色可以改变形状*/
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();
}
当我们想实现一个人物时,我们直接实例化一个人物对象,这样他就可以有运动和说话的动作了
const p = new People(10,12,16);
p.init();
桥接模式主要是对结构之间的解构,而抽象工厂模式与创建者模式主要业务在于创建。
通过侨联模式,使实现层与抽象层分开处理,避免需求的改变造成对象内部的修改,
体现了面向对象对扩展的开放及对修改的关闭原则。