这样可以解决Liskov替代方矩形违反问题吗? [英] Does this solve the Liskov Substitution square-rectangle violation?

查看:76
本文介绍了这样可以解决Liskov替代方矩形违反问题吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对SOLID设计原则非常陌生.我在理解上遇到的问题之一是违反Liskov替代原理的正方形"示例.为什么正方形的高度/宽度设置器会覆盖矩形的高度/宽度设置器?当存在多态性时,这难道不是问题的原因吗?

I'm very new to the SOLID design principles. One thing I had problem with understanding is the "Square-rectangle" example of a Liskov Substition Principle violation. Why should the Height/Width setter of a Square override the ones of a Rectangle? Isn't this exactly what's causing the problem when there's Polymorphism?

不删除它可以解决问题吗?

Doesn't removing this solve the problem?

class Rectangle
{
    public /*virtual*/ double Height { get; set; }
    public /*virtual*/ double Width { get; set; }
    public double Area() { return Height * Width; }
}

class Square : Rectangle
{
    double _width; 
    double _height;
    public /*override*/ double Height
    {
        get
        {
            return _height;
        }
        set
        {
            _height = _width = value;
        }
    }
    public /*override*/ double Width
    {
        get
        {
            return _width;
        }
        set
        {
            _width = _height = value;
        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        Rectangle r = new Square();
        r.Height = 5;
        r.Width = 6;

        Console.WriteLine(r.Area());
        Console.ReadLine();
    }
}

输出为预期的30.

推荐答案

想象用户正在GUI应用程序中实现边界框,类似于:

Imagine the user is implementing a bounding box in a GUI application, similar to this:

他们希望通过Rectangle类表示此蓝色框,以便在用户单击&向下拖动它的高度会增加;如果用户向右拖动,其宽度将增加.

They want to represent this blue box by a Rectangle class, so that if the user clicks & drags down its height will increase; if the user drags right, its width will increase.

LSP指出,无论您在哪里使用客户端的超类(矩形),客户端都应该能够在不破坏Rectangle的业务逻辑的情况下使用派生类(Square),即,用户应该能够为另一个& amp ;他们的其余代码不应中断.

LSP states that a client should be able to use a derived class (Square) wherever you would use its superclass (Rectangle) without breaking the business logic of Rectangle — i.e. a user should be able to sub in one for the other & the rest of their code shouldn't break.

但是以下内容彼此不兼容:

But the following are incompatible with each other:

  • 这是Rectangle的后置条件,它的setter方法不会引起副作用(即setWidth不应影响高度)
  • 正方形的逻辑固有的是宽度总是等于高度.
  • It's an assumed post-condition of Rectangle that it's setter methods won't cause side effects (i.e. setWidth shouldn't affect the height)
  • It's inherent to the logic of a Square that its width will always equal its height.

如果程序员使用Square而不是Rectangle,则上面的假设将不起作用,就像用户向下拖动一样,该框在水平方向上会变大&同时垂直放置.

If the programmer used Square instead of Rectangle, their assumption above wouldn't work, as if the user dragged down, the box would get bigger horizontally & vertically at the same time.

Square/Rectangle示例的麻烦之处在于,我们一开始对Rectangle的假设过多.矩形可以具有与其高度不同的长度,但这是特定类型的矩形(长方形矩形)的属性.

The trouble with the Square/Rectangle example is that we're assuming too much about Rectangle to begin with. A rectangle can have a different length to its height, but this is a property of a specific type of rectangle (an oblong rectangle).

一个正方形是一个矩形,但是一个正方形不是一个长方形.如果我们想假设关于Rectangle类的椭圆形的行为(宽度和高度可以不同),那么Square类从此扩展是没有意义的.

A square is a rectangle, but a square is not an oblong rectangle. If we want to assume the behaviour of an oblong about our Rectangle class (that it's width & height can differ), it's then doesn't make sense for our Square class to extend from that.

这篇关于这样可以解决Liskov替代方矩形违反问题吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆