在实际类设计过程中,有时会遇到此类情况:由于实际的需要,某个类具有两个或两个以上的维度变化,如果利用继承将每种可能的变化情况都定义成一个类,一是会导致类膨胀的问题,二是以后不太好维护和并且违背类的设计原则。那么面对这种情况,类改如何设计呢?这就是本文所要讲到的桥接模式。
简单的讲,桥接模式是指:将抽象和行为划分开来,从而将各个可能变化的维度分离开来,各自独立成一个类,但是能够动态的组合。
貌似有点抽象,下面通过一个简单的例子来理解桥接模式。
我们可以通过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已经隐含的作为桥接的父类,当然,设计模式是死的,人是活的,其实也可以单独定义出一个专门用于桥接目的的桥接类。