java設(shè)計模式--橋接模式詳解
引例
需求:對不同手機(jī)類型的不同品牌(比如按鍵手機(jī):諾基亞、翻蓋手機(jī):紐曼、智能手機(jī):華為、小米)實(shí)現(xiàn)操作編程(比如: 開機(jī)、關(guān)機(jī)、打電話)。
先來說說一般解法:將不同手機(jī)類型繼承父類手機(jī),最后各個品牌再繼承對應(yīng)手機(jī)類型:

弊端:乍一看沒問題,但其實(shí)不易擴(kuò)展(類爆炸),如果增加新的手機(jī)類型(比如新興的折疊式),就需要增加各個手機(jī)品牌的類去繼承(比如已繼承智能手機(jī)的華為小米)。同樣如果我們增加一個手機(jī)品牌,也要在各個手機(jī)樣式類下增加。違反了單一職責(zé)原則,維護(hù)成本高。
解決方案就是下面的主角:橋接模式。
橋接模式
橋接模式(Bridge)是一種結(jié)構(gòu)型設(shè)計模式。顧名思義,就像搭個橋連接起來,通過使用封裝、聚合及繼承等行為讓不同的類承擔(dān)不同的職責(zé),將實(shí)現(xiàn)與抽象放在兩個不同的類層次中,使兩個層次可以獨(dú)立改變,保持各部分的獨(dú)立性以及應(yīng)對他們的功能擴(kuò)展。
原理類圖:

- Client類:客戶端調(diào)用
- Abstraction抽象類:充當(dāng)橋接類,維護(hù)了Implementor接口(即它的實(shí)現(xiàn)類ConcreteImplementorA…)
- RefindAbstraction類:是抽象類的子類
- Implementor接口:行為實(shí)現(xiàn)接口
- ConcreteImplementorA/B類:行為的具體實(shí)現(xiàn)類
從UML類圖看出,抽象類和接口是聚合的關(guān)系,即調(diào)用和被調(diào)用的關(guān)系。如此一來搭好橋后,具體實(shí)現(xiàn)類調(diào)用方法=》父類抽象類的方法=》行為接口方法=》具體接口行為實(shí)現(xiàn)類,以完成連接,同時兩者又相互獨(dú)立易擴(kuò)展:

實(shí)戰(zhàn)示例
用橋接模式來解決引例的實(shí)際問題。
類圖:

代碼:
//接口
public interface Brand {
void open(); //開機(jī)
void close(); //關(guān)機(jī)
void call();//打電話
}
//接口實(shí)現(xiàn)類
public class NOKIA implements Brand{
@Override
public void open() {
System.out.println("諾基亞手機(jī)開機(jī)");
}
@Override
public void close() {
System.out.println("諾基亞手機(jī)關(guān)機(jī)");
}
@Override
public void call() {
System.out.println("諾基亞手機(jī)打電話");
}
}
public class Newsmy implements Brand{
@Override
public void open() {
System.out.println("紐曼手機(jī)開機(jī)");
}
@Override
public void close() {
System.out.println("紐曼手機(jī)關(guān)機(jī)");
}
@Override
public void call() {
System.out.println("紐曼手機(jī)打電話");
}
}
public class Huawei implements Brand{
@Override
public void open() {
System.out.println("華為手機(jī)開機(jī)");
}
@Override
public void close() {
System.out.println("華為手機(jī)關(guān)機(jī)");
}
@Override
public void call() {
System.out.println("華為手機(jī)打電話");
}
}
public class Xiaomi implements Brand{
@Override
public void open() {
System.out.println("小米手機(jī)開機(jī)");
}
@Override
public void close() {
System.out.println("小米手機(jī)關(guān)機(jī)");
}
@Override
public void call() {
System.out.println("小米手機(jī)打電話");
}
}
//抽象類
public abstract class Phone {
private Brand brand;//手機(jī)品牌接口
public Phone(Brand brand) {//構(gòu)造器
super();
this.brand = brand;
}
public void open() {
this.brand.open();
}
public void close() {
this.brand.close();
}
public void call() { this.brand.call(); }
}
//抽象子類
public class ButtonPhone extends Phone{
public ButtonPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("按鍵手機(jī)");
}
public void close() {
super.close();
System.out.println("按鍵手機(jī)");
}
public void call() {
super.call();
System.out.println("按鍵手機(jī)");
}
}
public class SlidePhone extends Phone{
public SlidePhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("翻蓋手機(jī)");
}
public void close() {
super.close();
System.out.println("翻蓋手機(jī)");
}
public void call() {
super.call();
System.out.println("翻蓋手機(jī)");
}
}
public class SmartPhone extends Phone{
public SmartPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("智能手機(jī)");
}
public void close() {
super.close();
System.out.println("智能手機(jī)");
}
public void call() {
super.call();
System.out.println("智能手機(jī)");
}
}
//客戶端調(diào)用
public class Client {
public static void main(String[] args) {
Phone phone1 = new ButtonPhone(new NOKIA());
phone1.open();
phone1.call();
phone1.close();
System.out.println("=======================");
Phone phone2 = new SlidePhone(new Newsmy());
phone2.open();
phone2.call();
phone2.close();
System.out.println("=======================");
Phone phone3 = new SmartPhone(new Huawei());
phone3.open();
phone3.call();
phone3.close();
}
}

總結(jié)
- 實(shí)現(xiàn)了抽象和實(shí)現(xiàn)部分的分離,從而極大的提供了系統(tǒng)的靈活性,讓抽象部分和實(shí)現(xiàn)部分獨(dú)立開來,這有助于系統(tǒng)進(jìn)行分層設(shè)計,從而產(chǎn)生更好的結(jié)構(gòu)化系統(tǒng)。
- 橋接模式替代多層繼承方案,可以減少子類的個數(shù),降低系統(tǒng)的管理和維護(hù)成本。
- 橋接模式的引入增加了系統(tǒng)的理解和設(shè)計難度,由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,要求開發(fā)者針對抽象進(jìn)行設(shè)計和編程
- 常見的應(yīng)用場景: -JDBC驅(qū)動程序
-銀行轉(zhuǎn)賬系統(tǒng)
轉(zhuǎn)賬分類: 網(wǎng)上轉(zhuǎn)賬,柜臺轉(zhuǎn)賬,AMT轉(zhuǎn)賬
轉(zhuǎn)賬用戶類型:普通用戶,銀卡用戶,金卡用戶…
-消息管理
消息類型:即時消息,延時消息
消息分類:手機(jī)短信,郵件消息,QQ消息…
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
SpringBoot中MapStruct實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制
本文主要介紹了SpringBoot中MapStruct實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-08-08
解決Java中socket使用getInputStream()阻塞問題
這篇文章主要介紹了解決Java中socket使用getInputStream()阻塞問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
java+selenium 網(wǎng)易云音樂刷累計聽歌數(shù)的方法
這篇文章主要介紹了java+selenium 網(wǎng)易云音樂刷累計聽歌數(shù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06

