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

弊端:乍一看沒(méi)問(wèn)題,但其實(shí)不易擴(kuò)展(類爆炸),如果增加新的手機(jī)類型(比如新興的折疊式),就需要增加各個(gè)手機(jī)品牌的類去繼承(比如已繼承智能手機(jī)的華為小米)。同樣如果我們?cè)黾右粋€(gè)手機(jī)品牌,也要在各個(gè)手機(jī)樣式類下增加。違反了單一職責(zé)原則,維護(hù)成本高。
解決方案就是下面的主角:橋接模式。
橋接模式
橋接模式(Bridge)是一種結(jié)構(gòu)型設(shè)計(jì)模式。顧名思義,就像搭個(gè)橋連接起來(lái),通過(guò)使用封裝、聚合及繼承等行為讓不同的類承擔(dān)不同的職責(zé),將實(shí)現(xiàn)與抽象放在兩個(gè)不同的類層次中,使兩個(gè)層次可以獨(dú)立改變,保持各部分的獨(dú)立性以及應(yīng)對(duì)他們的功能擴(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)系。如此一來(lái)搭好橋后,具體實(shí)現(xiàn)類調(diào)用方法=》父類抽象類的方法=》行為接口方法=》具體接口行為實(shí)現(xiàn)類,以完成連接,同時(shí)兩者又相互獨(dú)立易擴(kuò)展:

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

代碼:
//接口
public interface Brand {
void open(); //開(kāi)機(jī)
void close(); //關(guān)機(jī)
void call();//打電話
}
//接口實(shí)現(xiàn)類
public class NOKIA implements Brand{
@Override
public void open() {
System.out.println("諾基亞手機(jī)開(kāi)機(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ī)開(kāi)機(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ī)開(kāi)機(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ī)開(kāi)機(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ú)立開(kāi)來(lái),這有助于系統(tǒng)進(jìn)行分層設(shè)計(jì),從而產(chǎn)生更好的結(jié)構(gòu)化系統(tǒng)。
- 橋接模式替代多層繼承方案,可以減少子類的個(gè)數(shù),降低系統(tǒng)的管理和維護(hù)成本。
- 橋接模式的引入增加了系統(tǒng)的理解和設(shè)計(jì)難度,由于聚合關(guān)聯(lián)關(guān)系建立在抽象層,要求開(kāi)發(fā)者針對(duì)抽象進(jìn)行設(shè)計(jì)和編程
- 常見(jiàn)的應(yīng)用場(chǎng)景: -JDBC驅(qū)動(dòng)程序
-銀行轉(zhuǎn)賬系統(tǒng)
轉(zhuǎn)賬分類: 網(wǎng)上轉(zhuǎn)賬,柜臺(tái)轉(zhuǎn)賬,AMT轉(zhuǎn)賬
轉(zhuǎn)賬用戶類型:普通用戶,銀卡用戶,金卡用戶…
-消息管理
消息類型:即時(shí)消息,延時(shí)消息
消息分類:手機(jī)短信,郵件消息,QQ消息…
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
使用Java Collections實(shí)現(xiàn)集合排序的全面指南
在Java編程中,集合(Collection)是處理數(shù)據(jù)的重要工具之一,Java集合框架提供了豐富的接口和類來(lái)操作數(shù)據(jù)集合,而排序是其中最常見(jiàn)的操作之一,本文將詳細(xì)介紹如何使用Collections類對(duì)集合進(jìn)行排序,并深入探討其背后的原理和使用場(chǎng)景,需要的朋友可以參考下2025-02-02
Windows同時(shí)配置兩個(gè)jdk環(huán)境變量的操作步驟
Java Development Kit (JDK) 是開(kāi)發(fā)Java應(yīng)用程序的基礎(chǔ),包含了編譯器、調(diào)試器以及其他必要的工具,本指南將一步步指導(dǎo)您完成在Windows操作系統(tǒng)上同時(shí)配置兩個(gè)jdk環(huán)境變量的操作步驟,需要的朋友可以參考下2024-09-09
關(guān)于java.io.EOFException產(chǎn)生的原因以及解決方案
文章總結(jié):EOFException異常通常發(fā)生在嘗試從空的ObjectInputStream對(duì)象中讀取數(shù)據(jù)時(shí),解決方法是在finally語(yǔ)句中添加判斷,確保objectInputStream不為空后再進(jìn)行關(guān)閉操作,在處理1.txt文件為空的情況時(shí),捕獲EOFException可以避免程序終止,并且不會(huì)拋出空指針異常2025-01-01
運(yùn)行時(shí)常量池和字符串常量池的區(qū)別及說(shuō)明
這篇文章主要介紹了運(yùn)行時(shí)常量池和字符串常量池的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Java實(shí)現(xiàn)HttpGet請(qǐng)求傳body參數(shù)
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)HttpGet請(qǐng)求傳body參數(shù)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-02-02
java通過(guò)Idea遠(yuǎn)程一鍵部署springboot到Docker詳解
這篇文章主要介紹了java通過(guò)Idea遠(yuǎn)程一鍵部署springboot到Docker詳解,Idea是Java開(kāi)發(fā)利器,springboot是Java生態(tài)中最流行的微服務(wù)框架,docker是時(shí)下最火的容器技術(shù),那么它們結(jié)合在一起會(huì)產(chǎn)生什么化學(xué)反應(yīng)呢?的相關(guān)資料2019-06-06

