JavaScript设计模式———桥接模式
定义
桥接模式(Bridge),将抽象部分与实现部分分离,使他们可以独立的变化。
这种类型的设计模式属于结构型模式,它通过提供抽象化和实现化之间的桥接结构,来实现二者的解耦。
桥接模式需要一个 桥,来连接抽象部分和实现部分。
桥接模式,在系统中沿着多个维度变化,不仅不会增加系统的复杂度,还可以达到解耦的目的。
意图:将抽象与实现解耦。
抽象:在面向对象就是将对象共同的性质抽取出去而形成类的过程。
(JavaScript没有类的概念,可以理解为对象,进一步理解为函数,因为函数为一等公民也是对象)实现:针对抽象化给出的具体实现。它和抽象化是一个互逆的过程,实现化是对抽象化事物的进一步具体化。
(JavaScript没有类的概念,也就不需要具体化的过程,可以理解为对象具体调用的业务逻辑,或者对象被调用的具体上下文环境)
对于前端,比较常用的场景,是事件监控:
addEvent(element, 'click', getDrinkById);
function getDrinkById(e) {
var id = this.id;
asyncRequest('GET', 'drink.uri?id=' + id, function(resp) {
// callback response
console.log('Requested drink:' + resp.responseText);
});
}
但是上面代码有一个问题,就是getDrinkById必须有上下文,才能取得id,因为使用了this.id来取id.然后接着实现下面的逻辑,耦合过紧密。需要拆分:
addEvent(element, 'click', getDrinkByIdBridge);
// getDrinkByIdBridge作为桥 连接实现和抽象
function getDrinkByIdBridge(e) {
getDrinkById(this.id, function(drink) { console.log('Requested drink: ' + drink); });
}
function getDrinkById(id, callback) {
asyncRequest('GET', 'drink.uri?id=' + id, function(resp) {
// callback response
callback(resp.responseText);
});
}
从逻辑上分析,把id传给getDrinkById函数式合情理的,且响应结果总是通过一个回调函数返回。
现在做的是针对接口而不是实现进行编程,用桥接模式把抽象隔离开来。
此处的接口含义:接口是对象能响应的请求的集合
这样,明显代码模块话,各个部分代码功能明确,耦合性大大降低,将监听器方法抽取出来,成为一个单独的API函数,而且保证该API函数与节点本身没有必然的耦合,就可以独立的运行getDrinkById这个函数。
桥接模式,就是把给抽象与现实对象搭一座桥,让对象方法即联系在一起,又是独立变化的,让代码耦合性降低的一种设计模式。
多维变化的场景
桥接模式在多维变化的业务场景中,同样适用。如下示例,实现多元化对象,对抽象层和实现层进行解耦。
在传统面向对象编程中(有类的概念),使用组合来代替继承
// 桥接模式,实现多元化对象,对抽象层和实现层进行解耦
// 第1个抽象单元:运动单元
function Speed(x, y) {
this.x = x;
this.y = y;
}
Speed.prototype.run = function() {
console.log('run');
}
// 第2个抽象单元:着色单元
function Color(cl) {
this.color = cl;
}
Color.prototype.draw = function() {
console.log('draw');
}
// 第3个抽象单元:变形单位
function Shape(sp) {
this.shape = sp;
}
Shape.prototype.change = function() {
console.log('change');
}
// 第4个抽象单元:说话单元
function Speek(wd) {
this.word = wd;
}
Speek.prototype.say = function() {
console.log('say');
}
/*创建一个球类*/
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(s);
}
Spirite.prototype.init = function() {
this.speed.run();
this.color.draw();
this.shape.change();
}
// 测试用例
var p = new People(10, 12, 16);
p.init();
总结
桥接模式,最主要的特点是把实现层与抽象层进行解耦分离,使实现层和抽象层都可以在各个的维度上独立地变化。桥接模式是结构之间的解构。