桥接模式
概述
桥接模式(Bridge Pattern)是一种结构型设计模式,它将抽象部分与实现部分分离,使它们都可以独立地变化。桥接模式通过组合关系代替继承关系,降低了抽象和实现这两个可变维度的耦合度。
定义
桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
结构
桥接模式包含以下角色:
- 抽象类(Abstraction):定义抽象类的接口,维护一个指向实现类接口的引用
- 扩展抽象类(RefinedAbstraction):扩展抽象类,改变和修正父类对抽象的定义
- 实现类接口(Implementor):定义实现类的接口,这个接口不一定要与抽象类的接口完全一致
- 具体实现类(ConcreteImplementor):实现实现类接口,定义具体的实现
优缺点
优点
- 分离抽象和实现:桥接模式分离了抽象部分和实现部分,从而极大地提供了系统的灵活性
- 扩展性好:抽象部分和实现部分可以分别扩展,不会相互影响
- 实现细节对客户透明:客户可以针对抽象层编程,而不用关心实现细节
- 避免继承的缺点:使用组合关系代替继承关系,避免了继承的缺点
缺点
- 增加系统的理解与设计难度:由于关联关系建立在抽象层,要求开发者针对抽象进行设计与编程
- 要求正确识别出系统中两个独立变化的维度:桥接模式要求能够识别出系统中两个独立变化的维度
应用场景
- 当一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时
- 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时
- 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时
代码示例
示例 1:形状和颜色
// 实现类接口
interface Color {
void applyColor();
}
// 具体实现类
class RedColor implements Color {
@Override
public void applyColor() {
System.out.println("应用红色");
}
}
class BlueColor implements Color {
@Override
public void applyColor() {
System.out.println("应用蓝色");
}
}
// 抽象类
abstract class Shape {
protected Color color;
public Shape(Color color) {
this.color = color;
}
abstract public void applyColor();
}
// 扩展抽象类
class Circle extends Shape {
public Circle(Color color) {
super(color);
}
@Override
public void applyColor() {
System.out.print("圆形 ");
color.applyColor();
}
}
class Square extends Shape {
public Square(Color color) {
super(color);
}
@Override
public void applyColor() {
System.out.print("正方形 ");
color.applyColor();
}
}
// 客户端代码
public class BridgePatternDemo {
public static void main(String[] args) {
Color red = new RedColor();
Color blue = new BlueColor();
Shape circle = new Circle(red);
Shape square = new Square(blue);
circle.applyColor(); // 输出:圆形 应用红色
square.applyColor(); // 输出:正方形 应用蓝色
}
}
示例 2:消息发送系统
// 实现类接口
interface MessageSender {
void sendMessage(String message);
}
// 具体实现类
class EmailSender implements MessageSender {
@Override
public void sendMessage(String message) {
System.out.println("通过邮件发送: " + message);
}
}
class SMSSender implements MessageSender {
@Override
public void sendMessage(String message) {
System.out.println("通过短信发送: " + message);
}
}
// 抽象类
abstract class Message {
protected MessageSender sender;
public Message(MessageSender sender) {
this.sender = sender;
}
abstract public void send();
}
// 扩展抽象类
class UrgentMessage extends Message {
private String content;
public UrgentMessage(MessageSender sender, String content) {
super(sender);
this.content = "紧急: " + content;
}
@Override
public void send() {
sender.sendMessage(content);
}
}
class NormalMessage extends Message {
private String content;
public NormalMessage(MessageSender sender, String content) {
super(sender);
this.content = content;
}
@Override
public void send() {
sender.sendMessage(content);
}
}
// 客户端代码
public class MessageBridgeDemo {
public static void main(String[] args) {
MessageSender emailSender = new EmailSender();
MessageSender smsSender = new SMSSender();
Message urgentEmail = new UrgentMessage(emailSender, "系统维护通知");
Message normalSMS = new NormalMessage(smsSender, "日常提醒");
urgentEmail.send(); // 输出:通过邮件发送: 紧急: 系统维护通知
normalSMS.send(); // 输出:通过短信发送: 日常提醒
}
}
与其他模式的关系
- 适配器模式:适配器模式通常用于现有代码的集成,而桥接模式用于设计阶段
- 策略模式:桥接模式的结构与策略模式类似,但桥接模式关注的是抽象和实现的分离
- 抽象工厂模式:桥接模式可以与抽象工厂模式结合使用,工厂负责创建具体的实现对象
总结
桥接模式是一种非常有用的设计模式,它通过将抽象和实现分离,提供了更好的扩展性和灵活性。当系统中存在两个独立变化的维度时,桥接模式是一个很好的选择。它避免了继承的缺点,使用组合关系来实现功能的扩展。
