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

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

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

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

代碼:
//接口
public interface Brand {
void open(); //開機
void close(); //關(guān)機
void call();//打電話
}
//接口實現(xiàn)類
public class NOKIA implements Brand{
@Override
public void open() {
System.out.println("諾基亞手機開機");
}
@Override
public void close() {
System.out.println("諾基亞手機關(guān)機");
}
@Override
public void call() {
System.out.println("諾基亞手機打電話");
}
}
public class Newsmy implements Brand{
@Override
public void open() {
System.out.println("紐曼手機開機");
}
@Override
public void close() {
System.out.println("紐曼手機關(guān)機");
}
@Override
public void call() {
System.out.println("紐曼手機打電話");
}
}
public class Huawei implements Brand{
@Override
public void open() {
System.out.println("華為手機開機");
}
@Override
public void close() {
System.out.println("華為手機關(guān)機");
}
@Override
public void call() {
System.out.println("華為手機打電話");
}
}
public class Xiaomi implements Brand{
@Override
public void open() {
System.out.println("小米手機開機");
}
@Override
public void close() {
System.out.println("小米手機關(guān)機");
}
@Override
public void call() {
System.out.println("小米手機打電話");
}
}
//抽象類
public abstract class Phone {
private Brand brand;//手機品牌接口
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("按鍵手機");
}
public void close() {
super.close();
System.out.println("按鍵手機");
}
public void call() {
super.call();
System.out.println("按鍵手機");
}
}
public class SlidePhone extends Phone{
public SlidePhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("翻蓋手機");
}
public void close() {
super.close();
System.out.println("翻蓋手機");
}
public void call() {
super.call();
System.out.println("翻蓋手機");
}
}
public class SmartPhone extends Phone{
public SmartPhone(Brand brand) {
super(brand);
}
public void open() {
super.open();
System.out.println("智能手機");
}
public void close() {
super.close();
System.out.println("智能手機");
}
public void call() {
super.call();
System.out.println("智能手機");
}
}
//客戶端調(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é)
- 實現(xiàn)了抽象和實現(xiàn)部分的分離,從而極大的提供了系統(tǒng)的靈活性,讓抽象部分和實現(xiàn)部分獨立開來,這有助于系統(tǒng)進行分層設(shè)計,從而產(chǎn)生更好的結(jié)構(gòu)化系統(tǒng)。
- 橋接模式替代多層繼承方案,可以減少子類的個數(shù),降低系統(tǒng)的管理和維護成本。
- 橋接模式的引入增加了系統(tǒng)的理解和設(shè)計難度,由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,要求開發(fā)者針對抽象進行設(shè)計和編程
- 常見的應(yīng)用場景: -JDBC驅(qū)動程序
-銀行轉(zhuǎn)賬系統(tǒng)
轉(zhuǎn)賬分類: 網(wǎng)上轉(zhuǎn)賬,柜臺轉(zhuǎn)賬,AMT轉(zhuǎn)賬
轉(zhuǎn)賬用戶類型:普通用戶,銀卡用戶,金卡用戶…
-消息管理
消息類型:即時消息,延時消息
消息分類:手機短信,郵件消息,QQ消息…
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
SpringBoot中MapStruct實現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制
本文主要介紹了SpringBoot中MapStruct實現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制,文中通過示例代碼介紹的非常詳細,對大家的學(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ù)的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06

