9

适配器设计模式用于将类的接口(目标)转换为客户期望的另一个接口(适配器)。Adapter 让不兼容的类可以一起工作,因为它们的接口不兼容。

适配器模式可以通过两种方式实现,继承(适配器模式的类版本)和组合(适配器模式的对象版本)。

我的问题是关于使用继承实现的适配器模式的类版本。

这是绘图编辑器的示例:

图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和Shape对象不能互换使用。

是否应该更改 TextView 类以符合形状界面?也许不是。

TextShape 可以通过以下两种方式之一使 TextView 界面适应形状的界面:

  1. 通过继承Shape的接口和TextView的实现(Adapter模式的类版)
  2. 通过在 TextShape 对象内部组成一个 TextView 实例,并使用 TextView 实例(适配器模式的对象版本)实现 TextShape 的接口。

类适配器

图 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 的替代原则

4

1 回答 1

5

它不违反 Liskov 替换原则,除非您在子类中有某些东西使其行为方式对超类没有意义(违反超类的合同)。这当然是不完整的代码,但我没有看到任何迹象。

它可能违反单一职责原则,但我不确定这是适配器实现中的一个巨大问题。

我通常更喜欢委托方式。

于 2011-02-25T23:15:16.500 回答