適配器Adapter 設計模式

來源:互聯網
上載者:User
 歡迎轉載,請註明出處。 1、核心意圖:    將一個類的介面轉換成客戶希望的另外一個介面,從而使得原本由於介面不相容而不能一起工作的類可以一起工作。該模式的目標是通過一個代理(這裡是Adapter),在原來的類(Adaptee)和客戶(Client)之間進行協調,從而達到相容的目的。其核心是解決一致性的問題。  2、身邊執行個體:在我們實際生活中也很容易看到這方面的例子,比如我們要和一個外國人打交道,例如韓國人,如果我們沒有學習過韓語,這個韓國人也沒有學習過我們漢語,在這種情況下,我們之間是很難進行直接交流溝通。為了達到溝通的目的有兩個方法:1)改造這個韓國人,使其能夠用漢語進行溝通;2)請一個翻譯,在我們和這個韓國人之間進行語言的協調。顯然第一種方式——改造這個韓國人的代價要高一些,我們不僅要重新培訓他漢語的學習,還有時間、態度等等因素。而第二個方式——請一個翻譯,就很好實現,而且成本低,還比較靈活,當我們想換個日本人,再換個翻譯就可以了。  3、動機簡述:在該模式的動機中,描述了一個繪圖編輯器的實現,該編輯器可以對基本圖元Shape(直線、多邊形、本文等)進行繪製和排列來產生圖片和圖表,對於這些圖元類的實現,直線/多邊形還比較容易實現,但是本文的實現卻很麻煩,為了減少開發成本和保證品質,通過採用Adapter模式定義適配器類TextShape,來重用圖形工具箱中已經存在的本文編輯器TextView。  4、Java實現分析:在GOF設計模式中,Adapter可以分為類模式和對象模式兩種,類模式通過多重繼承實現,對象模式通過委託實現。在Java中由於沒有多重繼承機制,所以要想實作類別模式的Adapter,就要進行相應的改變:通過繼承Adaptee類實現Target介面方式實現。這種改變存在兩個問題:1)Target必須是一個介面而不能是一個類,否則Adapter無法implements實現;2)Adapter是繼承Adaptee的實現,而不是私人繼承,這就表示Adapter是一個Adaptee的子類。類Adapter模式和對象Adapter模式的Java代碼可參考本文下方代碼部分。  5、類模式/對象模式分析:由於存在兩種Adapter實現方式(即使在Java中),那麼在實際中我們採用哪一種要好呢?通過分析發現這兩種模式有兩個主要特性區別,並且還是互補的:  A、表現在Adapter對Adaptee的特殊性要求:類模式由於Adapter是Adaptee的子類,所以Adapter很方便重新定義Adaptee中的個別方法,以達到自己的特性需要。對象模式由於Adapter不是Adaptee的子類,所以如果Adapter對Adaptee中的個別方法有特殊的需要,就要建立Adaptee的子類,而讓Adapter使用這個子類。  B、表現在Adaptee的類層次擴充上:類模式由於Adapter是Adaptee的子類,所以編譯後就不能再更換所實現的父類Adaptee,因此如果有一個Adaptee的類階層,就要相應的有一個Adapter的類階層,且新擴充Adaptee時很不方便。對象模式由於Adapter不是Adaptee的子類,而是通過使用的方式,所以在系統運行時仍然可以更換Adapter所使用的Adaptee,只要他們具有相同的類型。所以在新擴充Adaptee時很方便。  6、Java程式碼範例—對象模式實現:類Point,表示畫面座標中的點
package qinysong.pattern.adapter;public class Point {  private int coordinateX;  private int coordinateY;  public Point(int coordinateX, int coordinateY){    this.coordinateX = coordinateX;    this.coordinateY = coordinateY;  }  public String toString(){    return "Point[x=" + coordinateX + ",y=" + coordinateY + "]";  }  public int getCoordinateX() {    return coordinateX;  }  public int getCoordinateY() {    return coordinateY;  }}

類Shape,表示圖元借口,對應Adapter模式中的Target

package qinysong.pattern.adapter;public interface Shape {  public Point getBottomLeftPoint();  public Point getTopRightPoint();}

類TextView,工具箱中的文本組件類,已經存在的類,對應Adapter模式中的Adaptee

package qinysong.pattern.adapter;public class TextView {  public int getCoordinateX() {    System.out.println("TextView.getCoordinateX()...");    return 10;  }  public int getCoordinateY() {    System.out.println("TextView.getCoordinateY()...");    return 20;  }  public int getHeight() {    System.out.println("TextView.getHeight()...");    return 30;  }  public int getWidth() {    System.out.println("TextView.getWidth()...");    return 40;  }  public boolean isEmpty(){    return false;  }}

類TextShape,對象模式實現的Adapterpackage qinysong.pattern.adapter;

public class TextShape implements Shape {  private TextView textView;  public TextShape(TextView textView){    this.textView = textView;  }  //通過TextView的執行個體進行協調實現  public Point getBottomLeftPoint() {    System.out.println("TextShape.getBottomLeftPoint()...");    int coordinateX = textView.getCoordinateX();    int coordinateY = textView.getCoordinateY();    return new Point(coordinateX, coordinateY);  }  //通過TextView的執行個體進行協調實現  public Point getTopRightPoint() {    System.out.println("TextShape.getTopRightPoint()...");    int coordinateX = textView.getCoordinateX();    int coordinateY = textView.getCoordinateY();    int height = textView.getHeight();    int width = textView.getWidth();    return new Point(coordinateX + width, coordinateY + height);  }}

類Client,Adapter模式的客戶

package qinysong.pattern.adapter;public class Client {  public static void main(String[] args){    System.out.println("Client.main begin ..........");    System.out.println("Client.main 以下是通過執行個體委託方式實現的Adapter");    Shape shape = new TextShape(new TextView());    Point bottomLeft = shape.getBottomLeftPoint();    Point topRight = shape.getTopRightPoint();    System.out.println("Client.main shape's bottomLeft:" + bottomLeft);    System.out.println("Client.main shape's topRight:" + topRight);    System.out.println(" Client.main 以下是通過類繼承方式實現的Adapter");    Shape shape2 = new TextShape2();    bottomLeft = shape2.getBottomLeftPoint();    topRight = shape2.getTopRightPoint();    System.out.println("Client.main shape2's bottomLeft:" + bottomLeft);    System.out.println("Client.main shape2's topRight:" + topRight);    System.out.println("Client.main end   ..........");  }}

7、Java程式碼範例—類模式實現:和以上對象模式實現中的樣本目的相同,類Point、Shape、TextView相同,略。以下是類TextShape2的範例程式碼,實作類別模式的Adapter

package qinysong.pattern.adapter;public class TextShape2 extends TextView implements Shape {  //通過所繼承的TextView,進行協調實現  public Point getBottomLeftPoint() {    System.out.println("TextShape2.getBottomLeftPoint()...");    int coordinateX = getCoordinateX();    int coordinateY = getCoordinateY();    return new Point(coordinateX, coordinateY);  }  //通過所繼承的TextView,進行協調實現  public Point getTopRightPoint() {    System.out.println("TextShape2.getTopRightPoint()...");    int coordinateX = getCoordinateX();    int coordinateY = getCoordinateY();    int height = getHeight();    int width = getWidth();    return new Point(coordinateX + width, coordinateY + height);  }  //注意: 這一點體現了類模式的優勢,可以很方便地重定義父類TextView中的方法  public int getCoordinateX() {    System.out.println("TextShape2.getCoordinateX()...");    return 100;  }}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.