2011-02-25 84 views
8

適配器設計模式用於將類(目標)的接口轉換爲另一個接口(Adaptee)客戶端期望的接口。適配器允許不兼容的類一起工作,否則因爲它們的不兼容的接口。適配器模式實現

適配器模式可以以兩種方式來實現,通過繼承(適配器模式的類版本),並通過組合物(對象適配器模式的版本)。

我的問題是關於使用繼承實現的適配器模式的類版本。

這裏是圖紙編輯器的一個例子:

Figure 1:

interface Shape 
{ 
     Rectangle BoundingBox(); 

     Manipulator CreateManipulator(); 
} 

class TextView 
{ 
     public TextView() { } 

     public Point GetOrigin() { } 

     public int GetWidth() { } 

     public int GetHeight() { } 
} 
interface Shape 
{ 
     Rectangle BoundingBox(); 

     Manipulator CreateManipulator(); 
} 

class TextView 
{ 
     public TextView() { } 

     public Point GetOrigin() { } 

     public int GetWidth() { } 

     public int GetHeight() { } 
} 

我們想重用的TextView類來實現TextShape,但接口不同,因此,TextView的和形狀對象不能可互換使用。

應該改變TextView類以符合形狀界面嗎?也許不是。

TextShape可以TextView的接口適應形狀的界面,在該兩種方法之一:

  1. 通過繼承形狀的界面和TextView中的實現(類版本適配器紋飾)
  2. 通過組成一個TextView實例在TextShape對象內部並使用TextView實例(適配器模式的對象版本)實現TextShape的界面。

類適配器

Figure 2:

interface Shape 
{ 
    Rectangle BoundingBox(); 

    Manipulator CreateManipulator(); 
} 

class TextView 
{ 
    public TextView() { } 

    public Point GetOrigin() { } 

    public int GetWidth() { } 

    public int GetHeight() { } 
} 

class TextShape : TextView, Shape 
{ 
    public Rectangle BoundingBox() 
    { 
     Rectangle rectangle; 
     int x, y; 
     Point p = GetOrigin(); 
     x = GetWidth(); 
     y = GetHeight(); 

     //... 

     return rectangle; 
    } 

    #region Shape Members 

    public Rectangle Shape.BoundingBox() 
    { 
     return new TextBoundingBox(); 
    } 

    public Manipulator Shape.CreateManipulator() 
    { 
     return new TextManipulator(); 
    } 

    #endregion 
} 

現在對於:-)的問題。 TextShape是否從Shape繼承,特別是從TextView中繼承有效的「是」關係?如果沒有,是不是違反了Liskov's Substitution Principle

+0

我認爲它不嚴格違反LSP,但爲什麼不使用排版方式?它更加分離。 – MatejB 2011-02-25 15:13:46

回答

4

它沒有違反Liskov替換原則,除非你在子類中有一些東西使得它的行爲方式對超類沒有意義(違反了超類的契約)。這當然是不完整的代碼,但我沒有看到任何跡象。

它可能違反了Single Responsibility Principle,但我不確定這是適配器實現中的一個巨大問題。

我通常更喜歡委託的方式。