Skip to content

桥接模式

桥接模式是一种结构型设计模式 (Structural Pattern),它将抽象部分 (Abstraction) 与它的实现部分 (Implementation) 分离,使它们可以独立地变化。

**特点 **

  1. 解耦抽象与实现:核心特点是将继承关系转换为组合/聚合关系,从而解耦抽象和实现。
  2. 高内聚,低耦合:抽象和实现可以独立地进行扩展和修改,互不影响。
  3. 提高可扩展性:在两个独立的维度(抽象和实现)上都可以自由地增加新的子类,而不会导致类数量急剧膨胀(避免了类爆炸)。
  4. 符合开闭原则:对扩展开放,对修改关闭。增加新的抽象或新的实现通常不需要修改现有代码。
  5. 客户端透明:客户端通过统一的抽象接口与对象交互,无需关心具体的实现细节。

**核心组成 **

  1. 抽象 (Abstraction):
    • 定义抽象接口,并包含一个对实现者接口的引用。
    • 客户端通过此接口与具体实现进行交互。
  2. 精炼抽象 (Refined Abstraction):
    • 继承自 Abstraction,是 Abstraction 的具体实现或扩展。
    • 可以添加新的行为或覆盖父类方法。
  3. 实现者接口 (Implementor):
    • 定义实现类的接口。这个接口不一定要与 Abstraction 的接口一致,通常提供更基本的操作。
    • 它是实现层次的顶层接口。
  4. 具体实现者 (Concrete Implementor):
    • 实现 Implementor 接口,在不同平台上实现 Implementor 接口的具体功能。

**核心思想 **

“组合优于继承”。当一个系统可能存在多个维度的变化(例如,一个图形既有形状变化,又有颜色/渲染方式变化),如果使用继承,会导致类的数量呈指数级增长(如 RedCircle, RedSquare, BlueCircle, BlueSquare...)。桥接模式通过将其中一个维度(通常是实现维度,如颜色/渲染方式)分离出来,形成独立的层次,并在抽象层次中持有对实现层次的引用,从而将两个维度解耦。这样,增加一种新形状或一种新颜色,都只需要增加一个类,而不会影响另一个维度。

合成/聚合复用原则

  • 组合(Composition)与聚合(Aggregation): 这两种都是“has-a”(有一个)的关系。一个类通过持有另一个类的实例作为自己的成员变量来使用其功能。
    • 组合 表示强拥有关系,整体和部分同生共死(如:发动机是汽车的一部分,汽车销毁,发动机也销毁)。
    • 聚合 表示弱拥有关系,整体和部分可以独立存在(如:汽车和司机,司机可以更换)。
  • 继承(Inheritance): 这是一种“is-a”(是一个)的关系。子类会获得父类的属性和方法。

为什么推荐组合/聚合?

  1. 降低耦合度: 组合/聚合的耦合度远低于继承。继承会将子类与父类紧密耦合,父类的任何修改都可能影响所有子类。而组合/聚合的类之间关系更松散,修改一个类对另一个类的影响较小。
  2. 更高的灵活性: 可以在运行时动态地改变组合/聚合的对象,从而改变行为。继承则是在编译时静态决定的。
  3. 避免继承的缺点: 继承容易导致类层次结构复杂、僵化,并且子类会不必要地暴露父类的接口和实现细节。

当需要复用某个功能时,优先考虑让一个类“包含”另一个能提供该功能的类(组合/聚合),而不是让这个类“成为”那个类的子类(继承)。这能让代码更灵活、更易维护和扩展。

使用场景

场景描述说明
存在多个独立变化的维度当一个类存在两个或多个独立变化的维度(如产品类型和制造方式、图形形状和渲染引擎、消息类型和发送渠道),且都需要扩展时。
避免继承体系的类爆炸当使用多层继承会导致子类数量急剧增加,形成复杂的继承树时。
希望抽象和实现都能独立扩展当需要让抽象部分和实现部分可以独立地进行修改和扩展,而互不影响。
实现细节对客户端透明希望客户端代码不依赖于具体的实现,只通过抽象接口进行操作。
运行时绑定实现需要在运行时动态地切换对象的具体实现。

示例:

抽象化接口(发送消息)

java
public interface MessageSend {
    String sendMessage(String message);
}

具体实现者(实现发送不同平台信息)

java
public class EmailSend implements MessageSend {
    @Override
    public String sendMessage(String message) {
        return "Email send message: " + message;
    }
}
java
public class WeChatSend implements MessageSend {
    @Override
    public String sendMessage(String message) {
        return "WeChat send message: " + message;
    }
}
java
public class QQSend implements MessageSend {
    @Override
    public String sendMessage(String message) {
        return "QQ send message: " + message;
    }
}

精炼抽象(抽象信息对象)

java
@AllArgsConstructor
public abstract class Message {

    protected MessageSend messageSend;

    public abstract String send(String message);
}

实现者(不同的信息类型)

java
public class NoticeMessage extends Message {
    public NoticeMessage(MessageSend messageSend) {
        super(messageSend);
    }

    @Override
    public String send(String message) {
        return "通知信息: " + messageSend.sendMessage(message);
    }
}
java
public class SystemMessage extends Message{

    public SystemMessage(MessageSend messageSend) {
        super(messageSend);
    }

    @Override
    public String send(String message) {
        return "系统信息: " + messageSend.sendMessage(message);
    }
}
最近更新