什么是桥接模式
桥接模式(Bridge Pattern)也称之为桥梁模式,接口(Interface)模式或者柄体(Handle and Body)模式,其核心思想是将抽象部分与它的实现部分分离,使抽象部分和实现部分两个维度都可以独立的变化。
桥接模式属于结构型模式,主要目的是通过组合的方式建立两个类之间的关系,而不是通过继承来实现,从而达到解耦抽象和实现的目的。
示例
在 Web 开发中,我们一般都有三种常见的发送消息的方式:站内信、短信(SMS)、邮件。而假如系统中的消息又需要按照紧急程度来划分普通消息和加急消息,那么这就有了两个维度:
- 抽象部分维度:发送消息的类型。
- 实现部分维度:普通消息和紧急消息。
下面就让我们以发送消息的这两个维度来实现一个桥接模式(这里我们需要新建一个 bridge 目录,相关类创建在 bridge 目录下)。
- 首先新建一个子系统 IMessage.java,这里面只定义一个发送消息的方法。 ```java package bridge;
public interface IMessage { void send(String content,String toUser);//发送消息 }
package bridge; public interface IMessage { void send(String content,String toUser);//发送消息 }
- 接下来需要建立三种消息类型之短信消息类 SmsMessage.java 并实现 IMessage 接口。
```java
package bridge;
public class SmsMessage implements IMessage {
@Override
public void send(String content, String toUser) {
System.out.println(String.format("SMS消息->%s:%s",toUser,content));
}
}
package bridge; public class SmsMessage implements IMessage { @Override public void send(String content, String toUser) { System.out.println(String.format(“SMS消息->%s:%s”,toUser,content)); } }
- 继续建立三种消息类型之邮件消息类 EmailMessage.java 并实现 IMessage 接口。 ```java package bridge;
public class EmailMessage implements IMessage { @Override public void send(String content, String toUser) { System.out.println(String.format(“邮件消息->%s:%s”,toUser,content)); } }
package bridge; public class EmailMessage implements IMessage { @Override public void send(String content, String toUser) { System.out.println(String.format("邮件消息->%s:%s",toUser,content)); } }
- 继续建立三种消息类型之站内消息类 WebMessage.java 并实现 IMessage 接口。
```java
package bridge;
public class WebMessage implements IMessage {
@Override
public void send(String content, String toUser) {
System.out.println(String.format("站内消息->%s:%s",toUser,content));
}
}
package bridge; public class WebMessage implements IMessage { @Override public void send(String content, String toUser) { System.out.println(String.format(“站内消息->%s:%s”,toUser,content)); } }
- 现在我们需要建立一个中介人即桥接者类 AbstractBridgeMessage.java,桥接者类一般设置为抽象类,其内部需要持有抽象维护(消息类型)的引用,并且定义和抽象维度类相同功能的方法。
package bridge;
public abstract class AbstractBridgeMessage {
private IMessage iMessage;//持有抽象维度的引用
public AbstractBridgeMessage(IMessage iMessage) {
this.iMessage = iMessage;
}
public void sendMessage(String content,String toUser){//定义一个和抽象维度类中具有相同功能的方法:发送消息
this.iMessage.send(content,toUser);//调用抽象维度内方法:发送消息
}
}
package bridge; public abstract class AbstractBridgeMessage { private IMessage iMessage;//持有抽象维度的引用 public AbstractBridgeMessage(IMessage iMessage) { this.iMessage = iMessage; } public void sendMessage(String content,String toUser){//定义一个和抽象维度类中具有相同功能的方法:发送消息 this.iMessage.send(content,toUser);//调用抽象维度内方法:发送消息 } }
- 接下来需要建立两个用于表示不同紧急程度的对象之普通消息 CommonMsg.java,并继承桥接者类 AbstractBridgeMessage,这就是桥接模式的核心之处,因为普通消息这个具体维度不去继承抽象维度,而是继承桥接者,这就实现了抽象和实现的解耦,桥接者在中间起到了桥梁的作用。
package bridge;
public class CommonMsg extends AbstractBridgeMessage {
public CommonMsg(IMessage iMessage) {
super(iMessage);
}
@Override
public void sendMessage(String content, String toUser) {
this.doSomething();//做一点普通消息该做的事
super.sendMessage(content, toUser);//调用桥接者中的方法:发送消息
}
private void doSomething() {
System.out.println("我只是一个普通消息,什么都不用做");
}
}
package bridge; public class CommonMsg extends AbstractBridgeMessage { public CommonMsg(IMessage iMessage) { super(iMessage); } @Override public void sendMessage(String content, String toUser) { this.doSomething();//做一点普通消息该做的事 super.sendMessage(content, toUser);//调用桥接者中的方法:发送消息 } private void doSomething() { System.out.println(“我只是一个普通消息,什么都不用做”); } }
- 最后再建立一个紧急消息类 UrgentMessage.java。
package bridge;
public class UrgentMessage extends AbstractBridgeMessage {
public UrgentMessage(IMessage iMessage) {
super(iMessage);
}
@Override
public void sendMessage(String content, String toUser) {
doSomething();//做点紧急消息需要做的事情
super.sendMessage(content, toUser);//调用桥接者中的方法:发送消息
}
private void doSomething() {
System.out.println("这是紧急消息,请优先发送");
}
}
package bridge; public class UrgentMessage extends AbstractBridgeMessage { public UrgentMessage(IMessage iMessage) { super(iMessage); } @Override public void sendMessage(String content, String toUser) { doSomething();//做点紧急消息需要做的事情 super.sendMessage(content, toUser);//调用桥接者中的方法:发送消息 } private void doSomething() { System.out.println(“这是紧急消息,请优先发送”); } }
- 现在可以建立一个测试类 TestBridge.java 来测试一下了。
package bridge;
import java.io.IOException;
public class TestBridge {
public static void main(String[] args) throws IOException {
IMessage iMessage = new EmailMessage();
AbstractBridgeMessage abstractBridgeMessage = new UrgentMessage(iMessage);//紧急邮件消息
abstractBridgeMessage.sendMessage("您好","双子孤狼1号");
//再来一个普通短信消息
System.out.println("------------分割线---------------");
iMessage = new SmsMessage();
abstractBridgeMessage = new CommonMsg(iMessage);
abstractBridgeMessage.sendMessage("您好","双子孤狼2号");
//最后再来一个紧急的站内信
System.out.println("------------分割线---------------");
iMessage = new WebMessage();
abstractBridgeMessage = new UrgentMessage(iMessage);
abstractBridgeMessage.sendMessage("您好","实验楼的小伙伴");
}
}
package bridge; import java.io.IOException; public class TestBridge { public static void main(String[] args) throws IOException { IMessage iMessage = new EmailMessage(); AbstractBridgeMessage abstractBridgeMessage = new UrgentMessage(iMessage);//紧急邮件消息 abstractBridgeMessage.sendMessage(“您好”,”双子孤狼1号”); //再来一个普通短信消息 System.out.println(“——————分割线———————-“); iMessage = new SmsMessage(); abstractBridgeMessage = new CommonMsg(iMessage); abstractBridgeMessage.sendMessage(“您好”,”双子孤狼2号”); //最后再来一个紧急的站内信 System.out.println(“——————分割线———————-“); iMessage = new WebMessage(); abstractBridgeMessage = new UrgentMessage(iMessage); abstractBridgeMessage.sendMessage(“您好”,”实验楼的小伙伴”); } }
执行 javac bridge/*.java 命令进行编译,然后再执行 java bridge.TestBridge 命令运行测试类(大家一定要自己动手运行哦,只有自己实际去运行了才会更能体会其中的思想)。
这就是一个桥接模式,后面这两个维度无论哪个维度需要扩展,都只需要新建一个类就好了,扩展起来非常的方便。