在实际类设计过程中,有时会遇到此类情况:由于实际的需要,某个类具有两个或两个以上的维度变化,如果利用继承将每种可能的变化情况都定义成一个类,一是会导致类膨胀的问题,二是以后不太好维护和并且违背类的设计原则。那么面对这种情况,类改如何设计呢?这就是本文所要讲到的桥接模式。
简单的讲,桥接模式是指:将抽象和行为划分开来,从而将各个可能变化的维度分离开来,各自独立成一个类,但是能够动态的组合。
貌似有点抽象,下面通过一个简单的例子来理解桥接模式。
我们可以通过Email发送信息,也可以手段短信发送信息(当然,以后很可能新增电报发信息等等),同时,根据信息的紧急程度,还可以分为紧急和普通(当然以后可能新增不紧急、特别紧急等等),桥接模式中类该怎么设计呢?
1.首先抽离出两个变化的维度:信息类型和和发信息的方式:
发信息接口:
1 interface SendMsgInterface {
2
3 public void sendMsg();
4
5 }
信息类型的抽象类:
1 abstract class Msg {
2
3 private SendMsgInterface smi;
4
5 public Msg(SendMsgInterface smi) {
6 this.smi = smi;
7 }
8
9 public abstract void send();
10
11 }
2.定义Emil发送方式类和Sms方式发送类:
1 class EmailSendMsg implements SendMsgInterface{
2
3 @Override
4 public void sendMsg() {
5 System.out.println("Email 方式发送");
6 }
7
8 }
1 class SmsSendMsg implements SendMsgInterface{
2
3 @Override
4 public void sendMsg() {
5 System.out.println("Sms 方式发送");
6 }
7
8 }
3.定义紧急信息和普通信息类:
1 class ImportantMsg extends Msg {
2
3 public ImportantMsg(SendMsgInterface smi) {
4 super(smi);
5 }
6
7 @Override
8 public void send() {
9 System.out.println("紧急信息");
10 }
11
12 }
1 class NormalMsg extends Msg {
2
3 public NormalMsg(SendMsgInterface smi) {
4 super(smi);
5 }
6
7 @Override
8 public void send() {
9 System.out.println("普通信息");
10 }
11
12 }
4.客户端测试:
public class BridgeTest {
public static void main(String[] args) {
// 以手机短信发送发送紧急信息
SendMsgInterface smdSendMsg = new SmsSendMsg();
Msg importantMsg = new ImportantMsg(smdSendMsg);
importantMsg.send();
}
}
看,桥接模式对于多个维度的变化处理起来很有优势。
按照其他的模式定义,如外观模式需要增加一个外观类,代理模式需要增加一个代理类等,在如上的桥接模式设计中,其实Msg已经隐含的作为桥接的父类,当然,设计模式是死的,人是活的,其实也可以单独定义出一个专门用于桥接目的的桥接类。