Does this solve the Liskov Substitution square-rectangle violation?

前端 未结 2 1741
离开以前
离开以前 2021-01-20 03:14

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

相关标签:
2条回答
  • 2021-01-20 03:55

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

    enter image description here

    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 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:

    • 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.

    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.


    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).

    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.

    0 讨论(0)
  • 2021-01-20 03:57

    The LSP states that substituting an object of a subclass should not change the behaviour, or the correctness, of the program. The classes you specify do change the correctness. With a rectangle, the client of the class expects that the height and width are independently settable. When you subclass with Square, this is no longer the case.

    A client setting a width of 5 and a height of 10, whilst reference an object that happens to be a Square but is held in a Rectangle variable, will get different results according to the order in which they set the height and width properties. They might get a 5x5 rectangle or a 10x10 one. Either case will be unexpected.

    There's Barbara's original complex description of LSP but Uncle Bob's makes it easier - "Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it". This is broken with the Square/Rectangle problem.

    I wrote an article about this at http://www.blackwasp.co.uk/SquareRectangle.aspx.

    0 讨论(0)
提交回复
热议问题