桥接模式
官方定义
将抽象部分与它的实现部分分离,使它们都可以独立地变化。
特点与个人理解
1.抽象与现实业务操作的解耦区分
把一些常用的操作抽象提取出来当成一个工具函数,再通过传参的区别发挥不同的功能,例如封装axios请求方法
// tool.js
export let sendRequest {
get(url,params) {
// 对get请求的参数做处理
return promise = axios({
method: 'get',
url,
params:params
}).then(() => {
// 对get请求的返回做处理
})
},
post(url,params) {
// 对post请求的参数做处理
return promise = axios({
method: 'post',
url,
data:params
}).then(() => {
// 对post请求的返回做处理
})
},
put() {},
delete() {},
option() {}, // 以后可以根据不同的请求方法做扩展
}
//api.js
export let api = {
api1: '/test/api1',
api2: '/test/api2',
// 以后可以根据不同的api做扩展
}
// 具体业务的页面
this.sendRequest.get(api1,{a:1}).then(() => { //具体的业务})
this.sendRequest.post(api2,{b:2}).then(() => { //具体的业务})
上面这个例子做得比较好的地方是把请求的方法抽象并且封装了起来,把请求方法和路径单独分了出来作为参数,方便日后的扩展;但是这个例子还不够的地方是请求方法和请求路径这两个维度的对照关系往往是唯一的,就是说通常对api1就是get,对api2就是post,(api1-post,api2-get的关系并不需要)没有体现出桥接模式的第二个特点。
2.两个不同维度的发展
假设现在有一个坐标轴,横轴是支付的渠道(可以微信,支付宝,京东,美团,云闪付等任意支付平台),纵轴是支付的方式(可以是刷脸,密码,指纹等),任意一个横轴的点都可以对应上各个纵轴的点并作出不同的功能
if(pay = "微信"){
if (payType = "刷脸") {} else (payType = "密码") {}
} else { pay = "支付宝") {
if (payType = "刷脸支付") {} else (payType = "密码支付") {}
}
把一二点结合一下,就是把两个会互相交织能产生多种变化的维度(即x1-y1,x1-y2;x2-y1,x2-y2)通过抽象的方法变成一种工具函数,便于在不同的场景中去使用,也便于这两个维度以后的增长和维护
桥接模式在前端的应用
硬是通过上面的特点举个简单的例子:抽象一个方法给dom节点加操作。x轴是不同的dom节点(dom1,dom2,dom3),y轴是节点常用事件(改变样式,清除浮动,stopPropagation, preventDefault)
// 抽象的方法
function addEvent(ele, fn) {
document.querySelector(ele).addEventListener('click', fn, false);
}
// 常用的基本操作
function changeStyle(dom) {
dom.style.color = 'red';
};
function preventDefault(dom) {
dom.preventDefault();
};
// 根据业务做不同的组合
addEvent('.dom1',changeStyle())
addEvent('#dom2',preventDefault())
总结
- 当有两个维度而且会有多种对应关系或者维度以后还会不断增长时适合使用桥接模式
- 需要抽象一个函数出来,当业务较为复杂时可能会比较困难,针对的业务场景很特殊;
- 相当有利于代码以后的扩展性和可维护性