我对设计和学习设计原则是个新手。
它说,从矩形派生正方形是违反利斯科夫替换原则的经典例子。
如果是这样的话,正确的设计应该是什么?
发布于 2009-06-23 03:54:23
我相信理由是这样的:
假设您有一个接受矩形并调整其宽度的方法:
public void SetWidth(Rectangle rect, int width)
{
    rect.Width = width;
}假设这个测试将通过,这应该是完全合理的,因为什么是矩形:
Rectangle rect = new Rectangle(50, 20); // width, height
SetWidth(rect, 100);
Assert.AreEqual(20, rect.Height);..。因为更改矩形的宽度不会影响其高度。
但是,假设您从Rectangle派生了一个新的Square类。根据定义,正方形的高度和宽度始终相等。让我们再试一次这个测试:
Rectangle rect = new Square(20); // both width and height
SetWidth(rect, 100);
Assert.AreEqual(20, rect.Height);该测试将失败,因为将正方形的宽度设置为100也会改变其高度。
因此,从矩形派生Square违反了Liskov的替换原则。
" is -a“规则在”现实世界“中是有意义的(正方形绝对是一种矩形),但在软件设计的世界中并不总是如此。
编辑
为了回答你的问题,正确的设计应该是Rectangle和Square都派生自一个公共的"Polygon“或"Shape”类,该类不强制执行任何关于宽度或高度的规则。
发布于 2009-06-23 04:00:16
答案取决于可变性。如果矩形和正方形类是不可变的,那么Square实际上是Rectangle的一个子类型,从second派生first是完全可以的。否则,Rectangle和Square都可以公开不带变形器的IRectangle,但是从另一个类型派生一个类型是错误的,因为这两个类型都不是另一个类型的子类型。
发布于 2009-06-23 04:11:26
我不同意从矩形派生正方形必然违反LSP。
在Matt的例子中,如果你的代码依赖于宽度和高度是独立的,那么它实际上就违反了LSP。
但是,如果你可以在不违反任何假设的情况下,在代码中的任何地方用矩形替换正方形,那么你就没有违反LSP。
因此,它实际上归结为抽象矩形在您的解决方案中意味着什么。
https://stackoverflow.com/questions/1030521
复制相似问题