桥接模式
将抽象部分与它的实现部分分离,使他们都可以独立地变化
就像一个桥,将两个变化维度连接起来。各个维度都可以独立的变化。故称之为:桥接模式
核心要点 : 处理多层继承结构,处理多维度变化的场景,将各个维度设计成独立的继承结构,使各个维度可以独立的扩展在抽象层建立关联。
桥接模式优点:
- 分离抽象部分和实现部分
桥梁模式分离了抽象部分和实现部分,从而极大的提高了系统的灵活性。让抽象部分和实现部分独立出来,分别定义接口,这有助于对系统进行分层,从而产生更好的结构化的系统。 - 更好的扩展性
桥梁模式使得抽象部分和实现部分可以分别独立的扩展,而不会相互影响,从而大大提高了系统的可扩展性。
桥接模式实际开发中应用场景:
JDBC驱动程序;
AWT中的Peer架构;
银行日志管理:
格式分类:操作日志、交易日志、异常日志
距离分类:本地记录日志、异地记录日志
人力资源系统中的奖金计算模块:
奖金分类:个人奖金、团体奖金、激励奖金。
部门分类:人事部门、销售部门、研发部门。
OA系统中的消息处理:
业务类型:普通消息、加急消息、特急消息
发送消息方式:系统内消息、手机短信、邮件
案例:
考虑这样一个实际的业务功能:
发送提示消息。基本上所有带业务流程处理的系统都会有这样的功能,比如OA上有未处理完毕的文件,需要发送一条消息提示他。
从业务上看,消息又分为普通消息、加急消息,不同的消息类型,业务功能处理是不一样的,比如加急消息是在消息上添加加急;从发送消息的手段上看,又有系统内短消息、邮件等。
定义一个发送消息方法的接口
package com.ung.mode.bridging;
/**
* @author: wenyi
* @create: 2022/9/28
* @Description: 桥接模式的 实现消息发送的接口
*/
public interface MessageImplementor {
//要发送的消息内容和接收人
void send(String message, String toUser);
}
发送消息方法接口的实现类
package com.ung.mode.bridging;
/**
* @author: wenyi
* @create: 2022/9/28
* @Description: 消息方法接口的实现类
*/
public class MessageEmail implements MessageImplementor {
@Override
public void send(String message, String toUser) {
System.out.println(String.format("使用邮件短消息的方法,发送消息 %s 给 %s", message, toUser));
}
}
package com.ung.mode.bridging;
/**
* @author: wenyi
* @create: 2022/9/28
* @Description: 消息方法接口的实现类
*/
public class MessageSMS implements MessageImplementor {
@Override
public void send(String message, String toUser) {
System.out.println(String.format("使用系统内部短消息的方法,发送消息 %s 给 %s", message, toUser));
}
}
定义抽象消息类
package com.ung.mode.bridging;
/**
* @author: wenyi
* @create: 2022/9/28
* @Description: 抽象的消息类
*/
public abstract class AbstractMessage {
//持有一个实现部分的对象
MessageImplementor implementor;
//构造方法,传入实现部分的对象
public AbstractMessage(MessageImplementor implementor) {
this.implementor = implementor;
}
//发送消息,委派给实现部分的方法
public void sendMessage(String message, String toUser) {
this.implementor.send(message, toUser);
}
}
普通消息类和加急消息类,继承抽象消息类
package com.ung.mode.bridging;
/**
* @author: wenyi
* @create: 2022/9/28
* @Description:
*/
public class CommonMessage extends AbstractMessage {
public CommonMessage(MessageImplementor implementor) {
super(implementor);
}
@Override
public void sendMessage(String message, String toUser) {
//普通消息,直接调用父类的方法
super.sendMessage(message, toUser);
}
}
package com.ung.mode.bridging;
/**
* @author: wenyi
* @create: 2022/9/28
* @Description:
*/
public class UrgencyMessage extends AbstractMessage {
public UrgencyMessage(MessageImplementor implementor) {
super(implementor);
}
@Override
public void sendMessage(String message, String toUser) {
//加急方式
super.sendMessage("加急" + message, toUser);
}
//拓展的子类功能
public Object watch(String messageId) {
//根据给定的id,查询获取消息的状态
return null;
}
}
测试
@Test
public void send() {
MessageImplementor messageSMS = new MessageSMS();
AbstractMessage commonMessage = new CommonMessage(messageSMS);
commonMessage.sendMessage("加班申请,速批", "老板");
MessageImplementor messageEmail = new MessageEmail();
AbstractMessage urgencyMessage = new UrgencyMessage(messageEmail);
urgencyMessage.sendMessage("加班申请,速批", "老板");
}
结果:
使用系统内部短消息的方法,发送消息 加班申请,速批 给 老板
使用邮件短消息的方法,发送消息 加急加班申请,速批 给 老板
总结:
就是将发送消息方法和 消息主体类进行抽象,使用不同的子类实现,来组合达到不同的效果
案例二
桥接的用意:
将抽象化与实现化解耦,使得二者可以独立变化,像我们常用的JDBCDriverManager一样,JDBC进行连接数据库的时候,在各个数据库之间进行切换,基本不需要动太多的代码,甚至丝毫不用动,原因就是JDBC提供统一接口,每个数据库提供各自的实现,用一个叫做数据库驱动的程序来桥接就行了
定义接口
package com.ung.mode.bridging.example2;
public interface Sourceable {
void method();
}
实现类1
package com.ung.mode.bridging.example2;
/**
* @author: wenyi
* @create: 2022/9/28
* @Description:
*/
public class SourceSub1 implements Sourceable {
@Override
public void method() {
System.out.println("sub 1");
}
}
package com.ung.mode.bridging.example2;
/**
* @author: wenyi
* @create: 2022/9/28
* @Description:
*/
public class SourceSub2 implements Sourceable {
@Override
public void method() {
System.out.println("sub 2");
}
}
定义具体操作方法的抽象父类
在这里面操作上面的接口实体
package com.ung.mode.bridging.example2;
public abstract class Bridge {
private Sourceable sourceable;
public void menthod() {
sourceable.method();
}
public Sourceable getSourceable() {
return sourceable;
}
public void setSourceable(Sourceable sourceable) {
this.sourceable = sourceable;
}
}
子类实现类
package com.ung.mode.bridging.example2;
/**
* @author: wenyi
* @create: 2022/9/28
* @Description:
*/
public class MyBridge extends Bridge {
public void method() {
getSourceable().method();
}
}
测试
@Test
public void menthod() {
Bridge bridge = new MyBridge();
//调用对象1
Sourceable source1 = new SourceSub1();
bridge.setSourceable(source1);
bridge.menthod();
//调用对象2
Sourceable source2 = new SourceSub2();
bridge.setSourceable(source2);
bridge.menthod();
}