写点什么

BridgePattern- 桥接模式

作者:梁歪歪 ♚
  • 2022 年 5 月 31 日
  • 本文字数:2926 字

    阅读完需:约 10 分钟

BridgePattern-桥接模式

桥接模式

桥接模式(Bridge Pattern):也称之为桥梁模式,接口(Interface)模式或者柄体(Handle and Body)模式,其核心思想是将抽象部分与它的实现部分分离,使抽象部分和实现部分两个维度都可以独立的变化。


桥接模式属于结构型模式,主要目的是通过组合的方式建立两个类之间的关系,而不是通过继承来实现,从而达到解耦抽象和实现的目的。


示例:在 Web 开发中,我们都有三种常见的发送消息的方式:站内信、短信(SMS)、邮件。而加入系统中的消息又需要按照紧急程度来划分普通消息和加急消息,那么这就有了两个维度。


  • 抽象部分维度:发送消息的类型

  • 实现部分维度:普通消息和紧急消息


我们就通过发送消息的这两个维度来举例说明...


  • 子系统IMessage.java


package cn.liangyy.bridge;
/** * 子系统 */public interface IMessage { /** * 发送消息 * @param content 消息内容 * @param toUser 接收者 */ void send(String content,String toUser);}
复制代码


  • 建立三种消息类型之短信消息类SmsMessage.java


package cn.liangyy.bridge;
/** * 短信消息类 */public class SmsMessage implements IMessage { /** * 发送消息 * @param content 消息内容 * @param toUser 接收者 */ @Override public void send(String content, String toUser) { System.out.println(String.format("SMS消息 --> %s:%s",toUser, content)); }}
复制代码


  • 建立三种消息类型之邮件消息类EmailMessage.java


package cn.liangyy.bridge;
/** * 邮件消息类 */public class EmailMessage implements IMessage { /** * 发送消息 * @param content 消息内容 * @param toUser 接收者 */ @Override public void send(String content, String toUser) { System.out.println(String.format("邮件消息 --> %s:%s",toUser, content)); }}
复制代码


  • 建立三种消息类型之站内消息类WebMessage.java


package cn.liangyy.bridge;
/** * 站内消息类 */public class WebMessage implements IMessage { /** * 发送消息 * @param content 消息内容 * @param toUser 接收者 */ @Override public void send(String content, String toUser) { System.out.println(String.format("站内消息 --> %s:%s",toUser, content)); }}
复制代码


  • 建立一个中介人即桥接者类AbstractBridgeMessage.java,桥接者类一般设置为抽象类,其内部需要持有抽象维护(消息类型)的引用,并且定义和抽象维度类相同功能的方法。


package cn.liangyy.bridge;
/** * 桥接者类 */public abstract class AbstractBridgeMessage { //持有抽象维度的引用 private IMessage iMessage;
public AbstractBridgeMessage(IMessage iMessage){ this.iMessage = iMessage; }
/** * 定义一个和抽象维度类中具有相同功能的方法:发送消息 * @param content * @param toUser */ public void sendMessage(String content,String toUser){ //调用抽象维度类中的方法 this.iMessage.send(content,toUser); }}
复制代码


  • 建立两个用于表示不同紧急程度的对象之普通消息CommonMsg.java,并继承桥接者类 AbstractBridgeMessage,这就是桥接模式的核心之处,因为普通消息这个具体维度不去继承抽象维度,而是继承桥接者,这就实现了抽象和实现的解耦,桥接者在中间起到了桥梁的作用。


package cn.liangyy.bridge;
/** * 普通消息 */public class CommonMsg extends AbstractBridgeMessage { public CommonMsg(IMessage iMessage) { super(iMessage); }
/** * 定义一个和抽象维度类中具有相同功能的方法:发送消息 * * @param content * @param toUser */ @Override public void sendMessage(String content, String toUser) { //做一点普通消息该做的事 this.doSomething(); //调用桥接者中的方法 super.sendMessage(content, toUser); }
private void doSomething(){ System.out.println("我只是一个普通消息,我什么都不用做!"); }}
复制代码


  • 紧急消息类UrgentMessage.java


package cn.liangyy.bridge;
/** * 紧急消息类 */public class UrgentMessage extends AbstractBridgeMessage { public UrgentMessage(IMessage iMessage) { super(iMessage); }
/** * 定义一个和抽象维度类中具有相同功能的方法:发送消息 * @param content * @param toUser */ @Override public void sendMessage(String content, String toUser) { //做点紧急消息需要做的事情 this.doSomething(); //调用桥接者中的方法 super.sendMessage(content, toUser); }
private void doSomething() { System.out.println("这是紧急消息,请优先发送!"); }}
复制代码


  • 测试TestBridge.java


package cn.liangyy.bridge;
/** * 桥接模式-测试 */public class TestBridge { public static void main(String[] args) { System.out.println("*******************************"); //紧急邮件消息 IMessage iMessage = new EmailMessage(); AbstractBridgeMessage abstractBridgeMessage = new UrgentMessage(iMessage); abstractBridgeMessage.sendMessage("你好!","亚索"); //普通短信消息 System.out.println("*******************************"); iMessage = new SmsMessage(); abstractBridgeMessage = new CommonMsg(iMessage); abstractBridgeMessage.sendMessage("你好!","武器");
//紧急站内信 System.out.println("*******************************"); iMessage = new WebMessage(); abstractBridgeMessage = new UrgentMessage(iMessage); abstractBridgeMessage.sendMessage("你好!","剑圣"); System.out.println("*******************************");
}}
复制代码


上述例子就是一个桥接模式,后面这两个维度无论哪个维度需要扩展,都只需新建一个类就可以了,扩展方便。


桥接模式适用场景


  • 在抽象和具体之间需要增加更多灵活性的场景。

  • 一个类存在 2 个或者以上独立变化的维度,而这些维度又需要独立进行扩展时,但是需要注意的是桥接模式一般用于抽象和实现解耦,多个维度一般是指的一个抽象维度和多个具体维度。

  • 不希望使用继承,或因为多层继承导致类的个数剧增时可以考虑使用桥接模式。


桥接模式优点


  • 分离了抽象部分及其实现部分两个维度,实现了代码的解耦,提高了系统的扩展性。

  • 扩展功能时只需要新增类,无需修改源代码,符合开闭原则。

  • 通过组合而不是继承来实现耦合,符合合成复用原则。


桥接模式缺点


  • 增加了系统的理解难度和设计难度(和类的膨胀缺点一样,这也算是大部分设计模式的共性)。

  • 需要正确识别系统中各个独立变化的维度。

发布于: 刚刚阅读数: 3
用户头像

梁歪歪 ♚

关注

还未添加个人签名 2021.07.22 加入

还未添加个人简介

评论

发布
暂无评论
BridgePattern-桥接模式_设计模式_梁歪歪 ♚_InfoQ写作社区