橋梁模式,我覺得是比較難理解的一個模式,它的定義很簡單:將抽象和實現解耦,讓它們可以獨立變化。深刻理解卻不容易。網上有很多案例,但這個模式如果以Demo
來聊,我覺得無法學到它的精髓。這邊以Dubbo
中Transporter
層的設計來說說橋梁模式。
這個模式比較隱晦,挺難理解的。什么是抽象,什么是實現?它這里面的抽象指的不是抽象類或者接口。實現也不是指的具體實現類。
我這邊來解釋下Transporter
層是怎么提現橋梁模式的,聲明下:這只是我個人的理解和觀點,并非官方給出。
Transporter
層的的抽象是指,Dubbo
抽象了一整套適合Dubbo
的網絡傳輸層的"類庫"。比如:看下Transporter
的接口代碼。
@SPI("netty")// 默認使用netty服務器
public interface Transporter {
// 抽象出了bind行為,這個行為要完成服務端口暴露的動作,并且返回Server抽象
// 無論netty,mina,grizzly或者其他的一些服務器暴露接口的動作叫啥名字,這邊都被抽象成了bind
// Exchange層只需要給URL和handler就可以完成端口暴露的動作
Server bind(URL url, ChannelHandler handler) throws RemotingException;
// 抽象出了connect行為,這個行為要完成客戶端與服務端的連接動作,并且返回Client抽象
// 無論netty,mina,grizzly或者其他的一些服務器做客戶端連接時叫啥名字,這邊都被抽象成了connect
// Exchange層只需要給URL和handler就可以完成端口暴露的動作
Client connect(URL url, ChannelHandler handler) throws RemotingException;
}
Dubbo
為每個服務器都做了Transporter
的適配。看下面的類圖結構。
image
除此之外,還有Server
,Client
,EndPoint
等都是Transporter
層做出的抽象。看下:
// 對交互兩端的抽象,分別是服務端和客戶端。
public interface Endpoint {
URL getUrl();
ChannelHandler getChannelHandler();
InetSocketAddress getLocalAddress();
void send(Object message) throws RemotingException;
void send(Object message, boolean sent) throws RemotingException;
void close();
void close(int timeout);
void startClose();
boolean isClosed();
}
// 對服務端的抽象
public interface Server extends Endpoint, Resetable {
boolean isBound();
Collection<Channel> getChannels();
Channel getChannel(InetSocketAddress remoteAddress);
}
// 對客戶端的抽象
public interface Client extends Endpoint, Channel, Resetable {
void reconnect() throws RemotingException;
}
上述所舉例子是Transporter
層所提現的抽象,在來看下橋梁模式中的實現。實現指的是跟具體服務器相關的一套類庫,分別Netty
,Mina
,Grizzly
各自的類庫。
這樣的設計完全提現了橋梁模式的定義:將抽象和實現解耦,讓它們可以獨立變化。
查看全部 淺談模式 - 匯總篇