Bridge Pattern
桥接模式的实现与应用场景
问题
什么是桥接模式?如何在 JavaScript 中实现?
解答
桥接模式将抽象与实现分离,让两者可以独立变化。当一个类存在两个或多个独立变化的维度时,使用桥接模式可以避免类爆炸。
场景示例:消息发送系统
假设有不同类型的消息(普通、紧急)和不同的发送方式(邮件、短信),如果用继承会产生 4 个类,维度增加时类数量会爆炸。
// 实现部分:发送方式
class MessageSender {
send(message) {
throw new Error('子类必须实现 send 方法');
}
}
class EmailSender extends MessageSender {
send(message) {
console.log(`通过邮件发送: ${message}`);
}
}
class SmsSender extends MessageSender {
send(message) {
console.log(`通过短信发送: ${message}`);
}
}
// 抽象部分:消息类型
class Message {
constructor(sender) {
// 桥接:持有实现部分的引用
this.sender = sender;
}
send(content) {
throw new Error('子类必须实现 send 方法');
}
}
class NormalMessage extends Message {
send(content) {
this.sender.send(`[普通] ${content}`);
}
}
class UrgentMessage extends Message {
send(content) {
this.sender.send(`[紧急!!!] ${content}`);
}
}
// 使用
const emailSender = new EmailSender();
const smsSender = new SmsSender();
const normalEmail = new NormalMessage(emailSender);
normalEmail.send('会议通知');
// 输出: 通过邮件发送: [普通] 会议通知
const urgentSms = new UrgentMessage(smsSender);
urgentSms.send('服务器宕机');
// 输出: 通过短信发送: [紧急!!!] 服务器宕机
前端实际应用:主题 + 组件
// 实现部分:主题
class Theme {
getStyles() {
throw new Error('子类必须实现');
}
}
class LightTheme extends Theme {
getStyles() {
return { background: '#fff', color: '#333' };
}
}
class DarkTheme extends Theme {
getStyles() {
return { background: '#333', color: '#fff' };
}
}
// 抽象部分:UI 组件
class UIComponent {
constructor(theme) {
this.theme = theme;
}
render() {
throw new Error('子类必须实现');
}
}
class Button extends UIComponent {
render() {
const styles = this.theme.getStyles();
return `<button style="background:${styles.background};color:${styles.color}">按钮</button>`;
}
}
class Input extends UIComponent {
render() {
const styles = this.theme.getStyles();
return `<input style="background:${styles.background};color:${styles.color}" />`;
}
}
// 使用:任意组合
const darkButton = new Button(new DarkTheme());
const lightInput = new Input(new LightTheme());
console.log(darkButton.render());
console.log(lightInput.render());
结构图
抽象部分 实现部分
┌───────────┐ ┌───────────┐
│ Message │──────────────│ Sender │
└─────┬─────┘ └─────┬─────┘
│ │
┌─────┴─────┐ ┌─────┴─────┐
│ │ │ │
┌───────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│Normal │ │ Urgent │ │ Email │ │ Sms │
└───────┘ └─────────┘ └─────────┘ └─────────┘
关键点
- 分离变化维度:将多个独立变化的维度拆分成独立的类层次
- 组合优于继承:通过组合而非继承来扩展功能,避免类爆炸
- 桥接引用:抽象部分持有实现部分的引用,运行时可动态切换
- 适用场景:跨平台 UI、多主题系统、多数据源适配
- 与策略模式区别:桥接强调结构分离,策略强调算法替换
目录