圖解Java設計模式之橋接模式

来源:https://www.cnblogs.com/haizai/archive/2020/03/21/12540294.html
-Advertisement-
Play Games

圖解Java設計模式之橋接模式 手機操作問題 傳統方案解決手機操作問題 傳統方案解決手機操作問題分析 橋接模式(Bridge)-基本介紹 橋接模式解決手機操作問題 橋接模式在JDBC中的源碼解析 橋接模式的註意事項和細節 橋接模式其它應用場景 手機操作問題 現在對不同手機類型的不同品牌實現操作編程( ...


圖解Java設計模式之橋接模式

 

手機操作問題

現在對不同手機類型的不同品牌實現操作編程(比如 :開機、關機、上網、打電話等等),如圖 :
在這裡插入圖片描述

傳統方案解決手機操作問題

傳統方法對應的類圖
在這裡插入圖片描述

傳統方案解決手機操作問題分析

1)擴展性問題(類爆炸),如果我們再增加手機的樣式(旋轉式),就需要增加各個品牌手機的類,同樣如果我們增加一個手機品牌,也要在各個手機樣式類下增加。
2)違反類單一職責原則,當我們增加手機樣式時,要同時增加所有品牌的手機,這樣增加類代碼維護成本。
3)解決方案 - 使用橋接模式

橋接模式(Bridge)-基本介紹

1)橋接模式(Bridge 模式)是指 : 將實現與抽象放在兩個不同的類層次中,使兩個層次可以獨立改變。
2)是一種結構型設計模式
3)Bridge模式基於類的最小設計原則,通過使用封裝、聚合及繼承等行為讓不同的類承擔不同的職責。它的主要特點是把抽象(Abstraction)與行為實現(Implementation)分離開來,從而可以保持各部分的獨立性以及應對他們的功能擴展。
在這裡插入圖片描述
說明 :
1)Client類 :橋接模式的調用者。
2)抽象類(Abstraction) :維護了Implementor / 即它的實現類ConcreteImplementorA…,二者是聚合關係,Abstraction充當橋接類。
3)RefinedAbstraction :是Abstraction抽象類的子類。
4)Implementor :行為實現類的介面
5)ConcreteImplementor A/ B : 行為的具體實現類
6)從UML圖 :這裡的抽象類和介面是聚合的關係,其實調用和被調用關係

橋接模式解決手機操作問題

使用橋接模式改進傳統方式,讓程式具有很好的擴展性,利用程式維護
1)應用實例和前面一樣
2)使用橋接模式對應的類圖
在這裡插入圖片描述

package com.example.demo.bridge;

/**
 * 介面
 * @author zhaozhaohai
 *
 */
public interface Brand {

	void open();
	void close();
	void call();
}
package com.example.demo.bridge;

public class Vivo implements Brand{

	@Override
	public void open() {
		// TODO Auto-generated method stub
		System.out.println("Vivo手機開機");
	}

	@Override
	public void close() {
		// TODO Auto-generated method stub
		System.out.println("Vivo手機關機");
	}

	@Override
	public void call() {
		// TODO Auto-generated method stub
		System.out.println("Vivo手機打電話");
	}

}
package com.example.demo.bridge;

public class XiaoMi implements Brand{

	@Override
	public void open() {
		// TODO Auto-generated method stub
		System.out.println("小米手機開機");
	}

	@Override
	public void close() {
		// TODO Auto-generated method stub
		System.out.println("小米手機關機");
	}

	@Override
	public void call() {
		// TODO Auto-generated method stub
		System.out.println("小米手機打電話");
	}

}
package com.example.demo.bridge;

public abstract class Phone {

	/**
	 * 組合品牌
	 */
	private Brand brand;
	
	public Phone(Brand brand) {
		this.brand = brand;
	}
	
	protected void open() {
		this.brand.open();
	}
	
	protected void close() {
		this.brand.close();
	}
	
	protected void call() {
		this.brand.call();
	}
}
package com.example.demo.bridge;

/**
 * 摺疊式手機類,繼承抽象類Phone
 * @author zhaozhaohai
 *
 */
public class FoldedPhone extends Phone{

	public FoldedPhone(Brand brand) {
		super(brand);
		// TODO Auto-generated constructor stub
	}
	public void open() {
		super.open();
		System.out.println(" 摺疊樣式手機 ");
	}
	
	public void close() {
		super.close();
		System.out.println(" 摺疊樣式手機 ");
	}
	
	public void cell() {
		super.call();
		System.out.println(" 摺疊樣式手機 ");
	}
}
package com.example.demo.bridge;

public class UpRightPhone extends Phone{

	public UpRightPhone(Brand brand) {
		super(brand);
		// TODO Auto-generated constructor stub
	}
	
	public void open() {
		super.open();
		System.out.println(" 直立樣式手機 ");
	}
	
	public void close() {
		super.close();
		System.out.println(" 直立樣式手機 ");
	}
	
	public void cell() {
		super.call();
		System.out.println(" 直立樣式手機 ");
	}

}
package com.example.demo.bridge;

public class Client {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 獲取摺疊式手機(樣式 + 品牌)
		Phone phone1 = new FoldedPhone(new XiaoMi());
		phone1.open();
		phone1.call();
		phone1.close();
		
		Phone phone2 = new FoldedPhone(new Vivo());
		phone2.open();
		phone2.call();
		phone2.close();
		
		Phone phone3 = new UpRightPhone(new XiaoMi());
		phone3.open();
		phone3.call();
		phone3.close();
	}

}

橋接模式在JDBC中的源碼解析

在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述

橋接模式的註意事項和細節

1)實現了抽象和實現部分的分離,從而極大的提供了系統的靈活性,讓抽象部分和實現部分獨立開來,這有助於系統進行分層設計,從而產生更好的結構化系統。
2)對於系統的高層部分,只需要知道抽象部分和實現部分的介面就可以了,其它部分由具體業務來完成。
3)橋接模式替代多層繼承方案,可以減少子類的個數,降低系統的管理和維護成本。
4)橋接模式的引入增加了系統的理解和設計難度,由於聚合關聯關係建立在抽象層,要求開發者針對抽象進行設計和編程
5)橋接模式要求正確識別出系統中兩個獨立變化的維度,因此其使用範圍有一定的局限性,即需要有這樣的應用場景。

橋接模式其它應用場景

1)對於那些不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加的系統,橋接模式尤為適用
2)常見的應用場景 :
JDBC驅動程式
銀行轉賬系統 :
轉賬分類 : 網上轉賬,櫃臺轉賬,AMT轉賬(抽象)
轉賬用戶類型 :普通用戶,銀卡用戶,金卡用戶(實現)
消息管理
消息類型 :即時消息,延時消息(抽象)
消息分類 :手機簡訊,郵件消息,QQ消息(實現)


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • JS排序演算法之快排和歸併 [Toc] 快速排序 原理: 選擇一個key(一般是第一個元素), 將數組劃分為兩個區域. 左邊全部區域小於等於key, 右邊全部大於key. 然後在通過這種方法將每個區域劃分為兩個區域. 整個過程可以遞歸實現,以此實現整個數據有序 + 時間複雜度: O(n log(n)) ...
  • 效果 貼上效果展示: 實現思路 樣式方面不多贅述,滾動區域是給固定高度,設置 來實現。 接下來看看js方面的實現,其實也很簡單,觸發的條件是: + = 。例子我會使用 來實現,和原生實現是一樣的。 可視高度(offsetHeight):通過 的 獲得,表示區域固定的高度。這裡我推薦通過 來獲取高度, ...
  • 為什麼要三次握手:① 防止失效的鏈接到達伺服器伺服器打開錯誤鏈接。② 客戶端如果長時間等待,會有一個超時重傳,但是之前那個被耽誤的請求還是會回到伺服器,伺服器會打開兩個連接。③ 有三次握手後客戶端會忽視滯留請求。 為什麼要四次揮手。 ① 當客戶端發送連接釋放報名後,伺服器端數據可能還沒有傳輸完。 為 ...
  • 淺拷貝 定義:直接將一個引用數據類型的地址,賦值給另一個變數存儲,兩個變數存儲的是相同的記憶體地址,在一個變數操作數據,另一個變數中的數據也會改變 案例: 總結: a給b賦值時是給的記憶體地址,兩個變數中的數據改變隨意一個變數的數據,另外一個變數中的數據也跟著改變,這種操作就被稱為淺拷貝 深拷貝 定義: ...
  • JavaScript進階之高階函數篇 簡介:歡迎大家來到woo爺說前端;今天給你們帶來的是JavaScript進階的知識,接下來的系列都是圍繞著JavaScript進階進行闡述;首先我們第一篇講的是高階函數。 高階函數定義:高階函數是指操作函數的函數;一般情況在項目開發過程中都會分兩種情況 函數可以 ...
  • JavaScript 中函數原型是實現繼承的基礎。prototype、construct、原型鏈以及基於原型鏈的繼承是面向對象的重要內容 ...
  • 故事背景: 沙雕在公司一個開放API團隊工作,平時的工作內容主要是做一些對外API項目開發,負責跟第三方系統對接。雖然工作也幾年了,但是一直都是按照上級做好的設計文檔和分配的任務去做,很少自己去做設計和思考。有一天團隊老大跑路了,部門老闆想提拔他做團隊老大的工作,但需要負責一個新項目架構設計工作來試 ...
  • 策略模式(Strategy):它定義了演算法家族,分別封裝起來,讓它們之間可以互相替換,此模式讓演算法的變化不會影響到使用演算法的客戶。 ——《大話設計模式》 策略模式主要用來解決當有多種相似演算法的時,使用if...else產生的難以維護的問題。它主要由三部分組成:Strategy介面、具體的Strate ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...