【问题标题】:Adapter Pattern vs Liskov Substitution适配器模式与 Liskov 替换
【发布时间】:2011-02-25 15:00:47
【问题描述】:

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

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

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

以下是绘图编辑器的示例:

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 的接口。

类适配器

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吗?

【问题讨论】:

  • 我认为它并没有严格违反LSP,但为什么不使用组合方式呢?它更加解耦。

标签: design-patterns adapter solid-principles liskov-substitution-principle


【解决方案1】:

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

它可能违反Single Responsibility Principle,但我不确定这是适配器实现中的一个大问题。

我通常更喜欢委托方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 2017-08-27
    • 2013-12-15
    相关资源
    最近更新 更多