Java桥接模式源码剖析及使用场景

一、介绍

它的主要目的是将抽象化与实现化分离,使得二者可以独立变化,就像一个桥,将两个变化维度连接起来。各个维度都可以独立的变化。故称之为:桥接模式

桥接模式的核心在于通过一个桥接接口,将抽象部分与实现部分解耦。这样做的好处是显而易见的,当系统中的某个维度(抽象或实现)需要变更时,不会影响到另一个维度。具体来说,桥接模式涉及以下几个关键角色:

  1. 抽象化角色(Abstraction):它是抽象类的接口,定义了一个实现化的引用和对实现化的操作。

  2. 修正抽象化角色(Refined Abstraction):它是扩展了抽象化角色的子类,在实际应用中,具体的业务逻辑通常在这个角色中实现。

  3. 实现化角色(Implementor):这个角色定义了一个接口,由具体实现化角色来实现。

  4. 具体实现化角色(Concrete Implementor):这个角色实现了实现化接口的具体类。

二、项目管理系统中使用桥接模式

需求:项目管理系统,包含多种任务(编码任务,测试任务)和多种任务执行(本地执行,远程执行)方式 。还有开发和测试角色。我们可以使用桥接模式来分离任务和任务执行方式的实现,以便它们可以独立变化。

  • 定义项目管理系统中的任务接口
public interface Task {
    void performTask();
}
  • 具体的任务实现类
// 编码任务
public class CodingTask implements Task {
    @Override
    public void performTask() {
        System.out.println("Performing coding task");
    }
}

// 测试任务
public class TestingTask implements Task {
    @Override
    public void performTask() {
        System.out.println("Performing testing task");
    }
}
  • 任务执行方式接口
public interface TaskExecution {
    void executeTask();
}
  • 具体的任务执行方式实现类
// 本地执行任务
public class LocalTaskExecution implements TaskExecution {
    @Override
    public void executeTask() {
        System.out.println("Executing task locally");
    }
}

// 远程执行任务
public class RemoteTaskExecution implements TaskExecution {
    @Override
    public void executeTask() {
        System.out.println("Executing task remotely");
    }

  • 项目管理系统角色抽象类
public abstract class ProjectRole {
    protected Task task;
    protected TaskExecution taskExecution;

    public void setTask(Task task) {
        this.task = task;
    }

    public void setTaskExecution(TaskExecution taskExecution) {
        this.taskExecution = taskExecution;
    }

    public abstract void performProjectTask();
}
  • 项目管理系统具体角色实现类
// 开发人员角色
public class Developer extends ProjectRole {
    @Override
    public void performProjectTask() {
        System.out.print("Developer role: ");
        task.performTask();
        System.out.print("Using ");
        taskExecution.executeTask();
    }
}

// 测试人员角色
public class Tester extends ProjectRole {
    @Override
    public void performProjectTask() {
        System.out.print("Tester role: ");
        task.performTask();
        System.out.print("Using ");
        taskExecution.executeTask();
    }
}
  • 客户端代码演示桥接模式的使用
public class BridgePatternDemo {
    public static void main(String[] args) {
        Task codingTask = new CodingTask();
        Task testingTask = new TestingTask();
        TaskExecution localTaskExecution = new LocalTaskExecution();
        TaskExecution remoteTaskExecution = new RemoteTaskExecution();

        // 创建不同角色的实例
        ProjectRole developer = new Developer();
        ProjectRole tester = new Tester();

        // 设置不同的任务和任务执行方式
        developer.setTask(codingTask);
        developer.setTaskExecution(remoteTaskExecution);

        tester.setTask(testingTask);
        tester.setTaskExecution(localTaskExecution);

        // 视图数据
        developer.performProjectTask();  // Output: "Developer role: Performing coding task Using Executing task remotely"
        tester.performProjectTask();   // Output: "Tester role: Performing testing task Using Executing task locally"
    }
}

大家说上面七步是桥接模式吗?在实际项目中,我们可以根据需要添加更多的任务和任务执行方式,而不需要修改已有的代码。核心在于正确识别并分离出两个独立的维度,并且这两个维度应该能够各自独立地变化和扩展。

三、权限管理中使用桥接模式

需求:权限管理系统,分别有普通角色、管理员角色、超级管理员角色。以数据权限设计,普通角色只能看到自己操作的数据,管理员角色可以看到普通角色操作的数据,超级管理员角色可以看到所有角色的数据。

  • 定义数据权限控制策略接口
public interface DataPermissionControlStrategy {
    void process();
}
  • 定义具体的数据权限控制策略实现类
// 普通角色只能看到自己操作的数据
public class NormalDataPermissionControlStrategy implements DataPermissionControlStrategy {
    @Override
    public void process() {
        System.out.println("Normal role can only access own data");
    }
}

// 管理员角色可以看到普通角色操作的数据
public class AdminDataPermissionControlStrategy implements DataPermissionControlStrategy {
    @Override
    public void process() {
        System.out.println("Admin role can access normal role's data");
    }
}

// 超级管理员角色可以看到所有角色的数据
public class SuperAdminDataPermissionControlStrategy implements DataPermissionControlStrategy {
    @Override
    public void process() {
        System.out.println("Super admin role can access all data");
    }
}
  • 定义用户角色抽象类
public abstract class UserRole {
    protected DataPermissionControlStrategy dataPermissionControlStrategy;

    public void setDataPermissionControlStrategy(DataPermissionControlStrategy dataPermissionControlStrategy) {
        this.dataPermissionControlStrategy = dataPermissionControlStrategy;
    }

    public abstract void viewData();
}
  • 定义具体的用户角色实现类
// 普通角色
public class NormalRole extends UserRole {
    @Override
    public void viewData() {
        System.out.print("Normal role: ");
        dataPermissionControlStrategy.process();
    }
}

// 管理员角色
public class AdminRole extends UserRole {
    @Override
    public void viewData() {
        System.out.print("Admin role: ");
        dataPermissionControlStrategy.process();
    }
}

// 超级管理员角色
public class SuperAdminRole extends UserRole {
    @Override
    public void viewData() {
        System.out.print("Super admin role: ");
        dataPermissionControlStrategy.process();
    }
}
  • 客户端代码演示桥接模式的使用
// 客户端代码演示桥接模式的使用
public class BridgePatternDemo {
    public static void main(String[] args) {
        DataPermissionControlStrategy normalStrategy = new NormalDataPermissionControlStrategy();
        DataPermissionControlStrategy adminStrategy = new AdminDataPermissionControlStrategy();
        DataPermissionControlStrategy superAdminStrategy = new SuperAdminDataPermissionControlStrategy();

        // 创建不同角色的实例
        UserRole normalUser = new NormalRole();
        UserRole adminUser = new AdminRole();
        UserRole superAdminUser = new SuperAdminRole();

        // 设置不同的数据权限控制策略
        normalUser.setDataPermissionControlStrategy(normalStrategy);
        adminUser.setDataPermissionControlStrategy(adminStrategy);
        superAdminUser.setDataPermissionControlStrategy(superAdminStrategy);

        // 视图数据
        normalUser.viewData();  // Output: "Normal role: Normal role can only access own data"
        adminUser.viewData();   // Output: "Admin role: Admin role can access normal role's data"
        superAdminUser.viewData();  // Output: "Super admin role: Super admin role can access all data"
    }
}

四、Java JDBC中使用桥接模式

在Java JDBC中,桥接模式并不是直接使用的设计模式。然而,在JDBC中,可以看到一些类似于桥接模式的结构和思想。

1.DataSource 接口:在JDBC中,DataSource 是一个接口,它提供了获取数据库连接的方法。不同的数据库厂商(比如MySQL、Oracle等)都会有对应的DataSource 实现类。这种设计类似于桥接模式中的抽象部分。

2.Connection 接口和实现类:Connection 接口代表着一个数据库连接,而具体的数据库连接操作是由各个数据库厂商提供的实现类来完成的,比如MySQLConnection、OracleConnection 等。这也体现了桥接模式中的实现部分。

通过接口和实现类的结合,实现了对不同数据库的访问和操作,并且很好地解耦了抽象和实现部分。

// 1.定义厂商DataSource 接口
public interface DataSource {
    Connection getConnection();
}

// 2.MySQLDataSource 实现类
public class MySQLDataSource implements DataSource {
    @Override
    public Connection getConnection() {
        // 返回 MySQL 数据库连接
        return new MySQLConnection();
    }
}

// 3.OracleDataSource 实现类
public class OracleDataSource implements DataSource {
    @Override
    public Connection getConnection() {
        // 返回 Oracle 数据库连接
        return new OracleConnection();
    }
}

// 4.不同的数据库不同的连接方法Connection 接口
public interface Connection {
    void executeQuery(String query);
}

// 5.MySQLConnection 实现类
public class MySQLConnection implements Connection {
    @Override
    public void executeQuery(String query) {
        // 在 MySQL 数据库中执行查询
        System.out.println("Executing query in MySQL database: " + query);
    }
}

// 6.OracleConnection 实现类
public class OracleConnection implements Connection {
    @Override
    public void executeQuery(String query) {
        // 在 Oracle 数据库中执行查询
        System.out.println("Executing query in Oracle database: " + query);
    }
}

  • 21
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
桥接模式是一种结构型设计模式,它可以将抽象部分与实现部分分离,使它们可以独立地变化。在桥接模式中,抽象部分和实现部分之间通过一个桥接接口相互连接。 下面是一个简单的 Java 桥接模式示例: 首先,我们需要定义一个实现接口(Implementor): ```java public interface Implementor { void operationImpl(); } ``` 然后,我们需要定义一个抽象类(Abstraction),它包含一个实现接口的引用: ```java public abstract class Abstraction { protected Implementor impl; public Abstraction(Implementor impl) { this.impl = impl; } public abstract void operation(); } ``` 接下来,我们需要定义具体的实现类(ConcreteImplementorA 和 ConcreteImplementorB): ```java public class ConcreteImplementorA implements Implementor { @Override public void operationImpl() { System.out.println("ConcreteImplementorA.operationImpl() called."); } } public class ConcreteImplementorB implements Implementor { @Override public void operationImpl() { System.out.println("ConcreteImplementorB.operationImpl() called."); } } ``` 最后,我们定义一个具体的抽象类(RefinedAbstraction),它通过实现抽象类中的 operation() 方法来调用实现接口中的 operationImpl() 方法: ```java public class RefinedAbstraction extends Abstraction { public RefinedAbstraction(Implementor impl) { super(impl); } @Override public void operation() { System.out.println("RefinedAbstraction.operation() called."); impl.operationImpl(); } } ``` 现在我们可以使用桥接模式来创建一个 RefineAbstraction 对象,并将其连接到 ConcreteImplementorA 或 ConcreteImplementorB 对象: ```java public static void main(String[] args) { Implementor implA = new ConcreteImplementorA(); Implementor implB = new ConcreteImplementorB(); Abstraction absA = new RefinedAbstraction(implA); Abstraction absB = new RefinedAbstraction(implB); absA.operation(); absB.operation(); } ``` 输出结果为: ``` RefinedAbstraction.operation() called. ConcreteImplementorA.operationImpl() called. RefinedAbstraction.operation() called. ConcreteImplementorB.operationImpl() called. ``` 这就是一个简单的 Java 桥接模式示例。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java语录精选

你的鼓励是我坚持下去的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值