設計模式之橋接模式


橋接模式

1.基本介紹

  • 橋接模式(Bridge)是指將實現與抽象放在兩個不同的類層次中,是兩個層次可以獨立改變
  • 該模式基於類的最小設計原則(擴展功能時盡量少的增加類),通過使用封裝、聚合、繼承等行為讓不同的類承擔不同的職責
  • 主要特點是把抽象和行為實現分離開來,從而可以保持各部分的獨立性以及對他們的功能擴展

2.原理類圖

  • client:橋接模式的調用者
  • 抽象類(Abstraction):維護了Implementor即他的實現類,二者是聚合關系,Abstraction充當橋接類
  • RefinedAbstraction:是Abstraction的子類
  • Implementor是行為實現類的接口

從UML圖看,這里的抽象類和接口是聚合關系,就是調用和被調用的關系;RefinedAbstraction的父類聚合了接口,RefinedAbstraction調用接口的具體實現

3.示例說明

  1. 如圖:由於手機品牌以及樣式的不同,每個手機的功能使用方式不相同,使用傳統的繼承方法,可以發現,每當我們擴展要增加一個新的品牌或者新的樣式時,都要添加n個類,特別的繁瑣,不易於開發

  1. 使用橋接模式對以上結構進行優化
    • 如圖,抽象類Phone聚合了品牌接口Brand,Phone的子類即手機樣式與品牌分隔開,選擇一個手機樣式,選擇一個品牌,然后將其在Phone中進行組合,得到想要產品,Phone則是充當橋梁的作用
    • 創建手機對象時,先選擇手機樣式,調用其父類聚合的Brand接口來獲取指定的手機品牌,而phone中的call操作則是直接調用brand中的call,以達到我們想要的效果
    • 如此擴展的時候,也不要添加很多的類,當你想要新增一個品牌,只需要在Brand多實現一個類即可,新增樣式也只需要在phone下繼承一個子類

  1. 代碼示例

    1. 定義Brand接口以及各個品牌的具體實現

      //定義接口
      public interface Brand {
      	public void call();
      }
      //Vivo實現
      class Vivo implements Brand{
      	@Override
      	public void call() {
      		// TODO Auto-generated method stub
      		System.out.println("Vivo 開機");
      	}
      	
      }
      //HuaWei實現
      class HuaWei implements Brand{
      	@Override
      	public void call() {
      		// TODO Auto-generated method stub
      		System.out.println("HuaWei 開機");
      	}
      }
      //XiaoMI實現
      class XiaoMI implements Brand{
      	@Override
      	public void call() {
      		// TODO Auto-generated method stub
      		System.out.println("XiaoMI 開機");
      	}
      }
      
    2. 編寫橋梁類即抽象類Phone

      public abstract class Phone {
      	//聚合Brand接口
      	private Brand brand;
      	//構造器:被子類調用
      	public Phone(Brand brand) {
      		this.brand = brand;
      	}
      	//定義手機功能,調用品牌的具體實現
          //注意該方法應該定義為protected,因為該方法還沒有完成,還需要子類的填充,所以不能被調用
      	protected void call() {
      		brand.call();
      	}
      }
      
    3. 舉例一個繼承Phone的子類Folder樣式手機

      public class FolderPhone  extends Phone{
      	//調用父類構造器,完成品牌手機的聚合
      	public FolderPhone(Brand brand) {
      		super(brand);
      	}
      	//重寫父類的call,調用父類的call方法,即保留品牌手機的操作,再加上樣式的特點,完成手機的功能實現
      	public void call() {
      		super.call();
      		System.out.println("添加了折疊手機的特色");
      	}
      }
      
    4. 而client調用時,只需要指定類型創建

      //指定折疊手機中的vivo品牌,便完成一個完整的手機
      Phone phone = new FolderPhone(new Vivo());
      

    以上則通過橋接模式完成一個手機功能,整個系統具有擴展性

4.JDBC中的橋接模式

JDBC在使用Driver獲取Connection中使用了橋接模式,但是和我們所說的結構有所不同,DriverManager不是一個抽象,但他使用的橋接模式的大致結構。

5.小結

  • 對於系統的高層來說,只需要知道抽象部分和實現部分的接口就夠了,其他部分由具體業務來完成
  • 橋接模式代替多層繼承方案,可以減少子類的個數,降低系統的管理和維護成本
  • 橋接模式要求正確識別出系統中的兩個獨立變化維度,因此其使用范圍有一定的局限性,適用於一定的應用場景

6.應用場景

  • 對於那些不希望使用繼承或因為多層次繼承導致系統類的個數急劇增加的系統,橋接模式猶為適用
  • 常用的場景:
    • JDBC驅動程序
    • 銀行轉賬系統
      • 轉賬分類:網上轉賬、櫃台轉賬、ATM轉賬
      • 用戶類型:普通用戶、銀卡用戶、金卡用戶
    • 消息管理
      • 消息類型:即時消息、延時消息
      • 消息分類:手機短信、郵件信息、QQ消息


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM