Java進階篇設計模式之四 -----介面卡模式和橋接模式

虛無境發表於2018-08-22

前言

上一篇中我們學習了建立型模式的建造者模式和原型模式。本篇則來學習下結構型模式的介面卡模式和橋接模式。

介面卡模式

簡介

介面卡模式是作為兩個不相容的介面之間的橋樑。這種型別的設計模式屬於結構型模式,它結合了兩個獨立介面的功能。

簡單的來說就是通過某個介面將不相容的兩個類進行相容,俗稱轉換器。 生活比較典型的例子是電器的電壓,美國的電壓是110V左右, 而中國的電壓普片是220V,如果我們想用美國或日本的電器,則需要一個轉換器,將110V轉換成220V。還有一個很典型例子就是曾經的萬能充,基本可以充各種手機的電池。

這裡我們用一個簡單的示例來進行說明。 某個視訊播放器,只能播放MP4格式的視訊,但是主流的視訊格式除了MP4,還有AVI、RVMB等,這時就有個軟體,格式工廠用於對視訊格式的轉換(介面卡),從而進行播放視訊。這時我們就可以使用介面卡模式來進行完成該程式碼的編寫。

介面卡模式主要有兩種型別,一種是類介面卡模式,主要通過繼承來實現介面卡功能;一種是物件介面卡模式,通過組合來實現介面卡功能。

首先是類介面卡模式,它需要完成一下步驟:

  1. 建立MP4、AVI、RVMB視訊格式的介面;
  2. 建立一個視訊播放器的類實現MP4視訊格式的類;
  3. 編寫一個格式工廠類,將AVI、RVMB等格式的視訊檔案轉換成MP4格式的檔案。
  4. 播放這些視訊。

那麼程式碼如下:

程式碼示例:


	interface Mp4{
		void playMp4();
	}
	
	interface Avi{
		void playAvi();
	}
	
	
	interface Rvmb{
		void playRvmb();
	}
	
	class VideoPlayer implements Mp4{
	
		@Override
		public void playMp4() {
			System.out.println("播放Mp4格式的視訊檔案.");
		}
	}
	
	
	class FormatFactory extends VideoPlayer  implements Avi{	
		@Override
		public void playAvi() {
			//轉換成MP4格式的視訊
			playMp4();
		}
	}
	
	
	public static void main(String[] args) {		
			Mp4 mp4=new VideoPlayer();
			mp4.playMp4();
			Avi avi=new FormatFactory();
			avi.playAvi();
	}
複製程式碼

執行結果:

	播放Mp4格式的視訊檔案.
	播放Mp4格式的視訊檔案.
複製程式碼

通過上述程式碼以及執行結果,我們可以得到想要的結果了,如果還有新增的視訊格式,也需要使用該視訊播放器播放的話,只需在增加一個介面以及格式工廠類就可以了。

物件介面卡模式 通過組合來實現介面卡功能。 所以這裡我們只需將格式工廠中繼承改為建立物件即可。 更改之後的程式碼如下: 程式碼示例


class FormatFactory2  implements Rvmb{
		private Mp4 mp4;
		
		 public FormatFactory2(Mp4 mp4) {
			this.mp4=mp4;
	   	}
		
		@Override
		public void playRvmb() {
			mp4.playMp4();
		}	
	}


	public static void main(String[] args) {
	
			Rvmb rvmb=new FormatFactory2(new VideoPlayer());
			rvmb.playRvmb();
			
	}
複製程式碼

執行結果:

	播放Mp4格式的視訊檔案.
複製程式碼

這兩種介面卡模式中,都實現了該功能,不過在這裡推薦使用物件介面卡模式,相比類介面卡模式,它更加靈活,也符合設計原則中的合成複用原則:

儘量使用合成/聚合的方式,而不是使用繼承。

介面卡模式的優點:

提升了類的複用和靈活度。

介面卡模式的缺點:

使用過多,系統會比較雜亂,難以把握。

注意事項:

介面卡不是在詳細設計時新增的,而是解決正在服役的專案的問題。

橋接模式

簡介

橋接是用於把抽象化與實現化解耦,使得二者可以獨立變化。這種型別的設計模式屬於結構型模式,它通過提供抽象化和實現化之間的橋接結構,來實現二者的解耦。

字面的意思解讀就是通過一箇中間的橋樑對兩邊的東西進行關聯起來,但是關聯的兩者之間又不相互影響。對這個印象比較深的是<大話設計模式>中的手機品牌和手機軟體,手機有很多品牌,市場有很多軟體,每個手機裝的軟體又各不相同,手機品牌包含包含軟體,但是軟體並不是手機的一部分,它們是聚合關係。如果A品牌手機裝了a,b軟體,B品牌手機裝了b,c軟體,如果A品牌手機需要新安裝一個c軟體,那麼它只需新增該軟體即可,無需知道該軟體是如何生產的。相同的,如果新增了一個C品牌手機,那麼它也只需安裝所需的a、b或c軟體即可。

好了,廢話不在多說,依舊用一個示例來進行說明。 市面上有很多種筆,比如鉛筆、黑色的圓珠筆和紅色的圓珠筆等等, 也有很多種型別的紙,比如考試的卷子用的紙,報紙用的紙等等。一般來說,報紙上的字顏色是黑色的,這裡我們就用黑色的圓珠筆來進行書寫,考試卷子上的打分字顏色是紅色的,這裡我們就用紅色的圓珠筆來進行書寫。筆類和紙類相互獨立,但是在紙上寫字又將它們關聯起來,這裡我們就可以使用橋接模式。

實現步驟如下:

  1. 定義一個筆類的介面,有寫的這個方法;
  2. 定義紅筆和黑筆的類,實現筆類的介面;
  3. 定義一個紙類的抽象類,設定筆的種類,並需要實現被寫的方法;
  4. 定義卷子紙和新聞紙類,繼承紙類並實現該方法;
  5. 進行書寫。

程式碼示例


interface Pen{
	void write();
}

class RedPen implements Pen{
	@Override
	public void write() {
		System.out.println("紅色的字");
	}
}

class BlackPen implements Pen{
	@Override
	public void write() {
		System.out.println("黑色的字");
	}
}


abstract class  Paper{
	protected  Pen pen;
	
	void setPen(Pen pen){
		this.pen=pen;
	}	
	abstract void writing();
}

class ExaminationPaper extends Paper{
	@Override
	void writing() {
		pen.write();
	}
}

class NewsPaper extends Paper{
	@Override
	void writing() {
		pen.write();
	}
}

public static void main(String[] args) {
		Paper paper=new ExaminationPaper();
		paper.setPen(new RedPen());
		paper.writing();
		
		Paper paper2=new NewsPaper();
		paper2.setPen(new BlackPen());
		paper2.writing();
	}
複製程式碼

執行結果

紅色的字
黑色的字
複製程式碼

從上述結果中我們可以得出我們想要的結果。如果新增一個筆類或者一個紙類,那麼只需新增相應的介面和實現即可,並不會因為結構化改變而相互直接影響。

橋接模式的優點:

1、抽象和實現的分離,實現瞭解耦; 2、提升的擴充套件能力。

橋接模式的缺點:

會使系統看起復雜,對新手不友好,沒有一定的抽象進行設計能力難以理解。

使用場景:

一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴充套件。

其它

音樂推薦

網易雲網友評價(ps:原版無法生成外鏈,建議聽原版):

扶桑畫師淺溪,居泰安,喜繪鯉。院前一方荷塘,錦鯉遊曳,溪常與嬉戲。 其時正武德之亂,藩鎮割據,戰事頻仍,魑魅魍魎,肆逆於道。兵戈逼泰安,街鄰皆逃亡,獨溪不捨錦鯉,未去。 是夜,院室倏火。有人入火護溪,言其本鯉中妖,欲取溪命,卻生情愫,遂不忍為之。翌日天明,火勢漸歇,人已不見。

原創不易,如果感覺不錯,希望給個推薦!您的支援是我寫作的最大動力! 版權宣告: 作者:虛無境 部落格園出處:www.cnblogs.com/xuwujing CSDN出處:blog.csdn.net/qazwsxpcm     個人部落格出處:www.panchengming.com

相關文章