在上一篇中咱們學習了建立型模式的建造者模式和原型模式。本篇則來學習下結構型模式的適配器模式和橋接模式。html
簡介設計模式
適配器模式是做爲兩個不兼容的接口之間的橋樑。這種類型的設計模式屬於結構型模式,它結合了兩個獨立接口的功能。ide
簡單的來講就是經過某個接口將不兼容的兩個類進行兼容,俗稱轉換器。
生活比較典型的例子是電器的電壓,美國的電壓是110V左右, 而中國的電壓普片是220V,若是咱們想用美國或日本的電器,則須要一個轉換器,將110V轉換成220V。還有一個很典型例子就是曾經的萬能充,基本能夠充各類手機的電池。學習
這裏咱們用一個簡單的示例來進行說明。
某個視頻播放器,只能播放MP4格式的視頻,可是主流的視頻格式除了MP4,還有AVI、RVMB等,這時就有個軟件,格式工廠用於對視頻格式的轉換(適配器),從而進行播放視頻。這時咱們就可使用適配器模式來進行完成該代碼的編寫。this
適配器模式主要有兩種類型,一種是類適配器模式,主要經過繼承來實現適配器功能;一種是對象適配器模式,經過組合來實現適配器功能。.net
首先是類適配器模式,它須要完成一下步驟:設計
那麼代碼以下:code
代碼示例:orm
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軟件便可。
好了,廢話不在多說,依舊用一個示例來進行說明。
市面上有不少種筆,好比鉛筆、黑色的圓珠筆和紅色的圓珠筆等等, 也有不少種類型的紙,好比考試的卷子用的紙,報紙用的紙等等。通常來講,報紙上的字顏色是黑色的,這裏咱們就用黑色的圓珠筆來進行書寫,考試卷子上的打分字顏色是紅色的,這裏咱們就用紅色的圓珠筆來進行書寫。筆類和紙類相互獨立,可是在紙上寫字又將它們關聯起來,這裏咱們就可使用橋接模式。
實現步驟以下:
代碼示例
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(); }
運行結果
紅色的字 黑色的字
從上述結果中咱們能夠得出咱們想要的結果。若是新增一個筆類或者一個紙類,那麼只需新增相應的接口和實現便可,並不會由於結構化改變而相互直接影響。
橋接模式的優勢:
一、抽象和實現的分離,實現瞭解耦;
二、提高的擴展能力。
橋接模式的缺點:
會使系統看起復雜,對新手不友好,沒有必定的抽象進行設計能力難以理解。
使用場景:
一個類存在兩個獨立變化的維度,且這兩個維度都須要進行擴展。
網易雲網友評價(ps:原版沒法生成外鏈,建議聽原版):
扶桑畫師淺溪,居泰安,喜繪鯉。院前一方荷塘,錦鯉遊曳,溪常與嬉戲。 其時正武德之亂,藩鎮割據,戰事頻仍,魑魅魍魎,肆逆於道。兵戈逼泰安,街鄰皆逃亡,獨溪不捨錦鯉,未去。 是夜,院室倏火。有人入火護溪,言其本鯉中妖,欲取溪命,卻生情愫,遂不忍爲之。翌日天明,火勢漸歇,人已不見。
原創不易,若是感受不錯,但願給個推薦!您的支持是我寫做的最大動力! 版權聲明: 做者:虛無境 博客園出處:http://www.cnblogs.com/xuwujing CSDN出處:http://blog.csdn.net/qazwsxpcm 我的博客出處:http://www.panchengming.com