设计模式:桥接模式

发布于:2024-05-07 ⋅ 阅读:(33) ⋅ 点赞:(0)

一、什么是桥接模式

接模式是一种对象结构型模式,它将抽象部分与它的实现部分分离,使它们都可以独立地变化。这种分离允许抽象和实现部分独立地扩展,而不会相互影响。桥接模式基于类的最小设计原则,通过封装、聚合及继承等行为让不同的类承担不同的职责。

二、桥接模式结构

在这里插入图片描述
桥接模式包含以下主要角色:

  • 抽象化(Abstraction)角色:定义抽象类,并包含一个对实现化对象的引用。
  • 扩展抽象化(Refined Abstraction)角色:是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。
  • 实现化(Implementor)角色:定义实现化角色的接口,供扩展抽象化角色调用。

在Java中,桥接模式可以通过接口和抽象类来实现。下面是一个简单的桥接模式的Java实现示例:

// 实现化角色接口  
public interface Implementor {  
    void operationImpl();  
}  
  
// 实现化角色A的具体实现  
public class ConcreteImplementorA implements Implementor {  
    @Override  
    public void operationImpl() {  
        System.out.println("ConcreteImplementorA operation");  
    }  
}  
  
// 实现化角色B的具体实现  
public class ConcreteImplementorB implements Implementor {  
    @Override  
    public void operationImpl() {  
        System.out.println("ConcreteImplementorB operation");  
    }  
}  
  
// 抽象化角色  
public abstract class Abstraction {  
    protected Implementor implementor;  
  
    // 构造器传入实现化对象  
    public Abstraction(Implementor implementor) {  
        this.implementor = implementor;  
    }  
  
    // 声明业务方法  
    public abstract void operation();  
  
    // 模板方法,调用实现化方法  
    protected void operationImpl() {  
        if (implementor != null) {  
            implementor.operationImpl();  
        }  
    }  
}  
  
// 扩展抽象化角色A  
public class RefinedAbstractionA extends Abstraction {  
    public RefinedAbstractionA(Implementor implementor) {  
        super(implementor);  
    }  
  
    // 实现业务方法  
    @Override  
    public void operation() {  
        System.out.println("RefinedAbstractionA operation");  
        operationImpl(); // 调用实现化方法  
    }  
}  
  
// 客户端代码  
public class Client {  
    public static void main(String[] args) {  
        // 创建实现化对象  
        Implementor implementorA = new ConcreteImplementorA();  
        Implementor implementorB = new ConcreteImplementorB();  
  
        // 创建抽象化对象并传入实现化对象  
        Abstraction abstractionA = new RefinedAbstractionA(implementorA);  
        Abstraction abstractionB = new RefinedAbstractionA(implementorB);  
  
        // 调用业务方法  
        abstractionA.operation(); // 输出: RefinedAbstractionA operation  
                                  //       ConcreteImplementorA operation  
        abstractionB.operation(); // 输出: RefinedAbstractionA operation  
                                  //       ConcreteImplementorB operation  
    }  
}

在这个例子中,Implementor是实现化角色接口,ConcreteImplementorA和ConcreteImplementorB是具体的实现类。Abstraction是抽象化角色,其中包含一个对实现化角色的引用,并定义了一个抽象的业务方法operation()。RefinedAbstractionA是扩展抽象化角色,实现了operation()方法,并调用了实现化角色的方法。

在客户端代码中,我们创建了两个不同的实现化对象,并将它们分别传递给扩展抽象化对象。然后,我们调用扩展抽象化对象的业务方法,该方法会首先输出自己的业务逻辑,然后调用实现化对象的方法。

这样,抽象化角色和实现化角色就可以独立地变化,它们之间的耦合度被降低了。如果需要添加新的实现化角色或扩展抽象化角色,只需要在相应的位置添加新的类即可,而不需要修改已有的代码。

三、桥接模式的应用场景

1、桥接模式适用的业务场景

  • 在抽象和具体实现之间需要增加更多的灵活性的场景。
  • 一个类存在两个或多个独立变化的维度,而这两个或多个维度都需要独立进行扩展。
  • 不希望使用继承,或因为多层继承导致系统类的个数剧增。桥接模式的一个常用场景就是为了替换继承。

通过桥接模式,可以实现系统从多个维度进行分类,将各维度抽象出来,各维度独立变化,之后可通过聚合,将各维度组合起来,减少了各维度间的耦合。这种设计模式可以提高代码的灵活性、可重用性和可扩展性。

2、桥接模式适用的具体的业务场景

  • 跨平台软件开发:当需要开发一个可以在多种操作系统或硬件平台上运行的应用程序时,可以使用桥接模式。例如,图形用户界面(GUI)的组件可以设计为抽象的,而具体的渲染逻辑则依赖于特定的平台实现。

  • 多种数据源的访问:当需要访问多种数据源(如数据库、文件、网络服务等)时,可以使用桥接模式。在这种情况下,数据源访问的抽象接口可以保持不变,而具体的访问实现则可以根据数据源类型进行变化。

  • 多种产品系列:在产品线中,可能存在多个产品系列,每个系列都有其独特的特点和实现方式。使用桥接模式,可以将产品的抽象部分(如接口或基类)与具体实现部分(如不同系列的实现)分离,从而简化产品线的维护和扩展。

  • 可扩展的图形库:在图形库中,可能需要支持多种图形形状和渲染方式。使用桥接模式,可以将图形的抽象定义(如形状、大小、颜色等)与具体的渲染实现(如OpenGL、DirectX等)分离,使得图形库更加灵活和可扩展。

  • 插件式架构:在插件式架构中,主程序提供一个稳定的接口或抽象类,而具体的功能则由插件来实现。桥接模式可以用于这种场景,将主程序的抽象部分与插件的具体实现部分分离,使得插件可以独立地开发、测试和替换。

  • 复杂的系统配置:在某些复杂的系统中,可能需要根据用户的不同需求或环境的不同配置来调整系统的行为。使用桥接模式,可以将系统的配置抽象为接口或基类,而将具体的配置实现作为实现化角色进行分离。这样,可以方便地切换不同的配置实现,以满足不同的需求。

  • 多语言支持:在需要支持多种语言的软件中,可以使用桥接模式将语言的抽象定义(如字符串、日期格式等)与具体的语言实现(如英文、中文、法文等)分离。这样,可以方便地添加新的语言支持或修改现有语言的实现。

总的来说,桥接模式适用于那些需要将抽象部分与实现部分分离、减少它们之间耦合度的场景。通过桥接模式,可以使得抽象部分和实现部分能够独立地变化,从而提高系统的灵活性和可扩展性。