【问题标题】:If Field > CharField > EmailField, does EmailField break Liskov Substitution Principle with CharField?如果 Field > CharField > EmailField,EmailField 是否打破了 CharField 的 Liskov 替换原则?
【发布时间】:2013-06-07 12:47:59
【问题描述】:

假设我正在编写一个带有 Form 类的 webapp,而一个 Form 类可以有多个 Fields

Field 本身就是一个抽象类。它包含一个抽象的validators 属性,它是一个方法列表,它将调用以确定该字段的内容是否有效。这些验证器由实例方法Field.run_validators(value)调用来调用

CharField 是一个Field 子类,它允许任意文本。这个字段总是有效的,只要给它一些非零长度的字符串。

EmailField 是具有附加要求的 CharField 子类。此字段仅在value 通过某种测试时有效。 (例如'@' in value)。

我的问题是:EmailField 是否破坏了相对于CharField 的 LSP?它应该是一个兄弟类吗?尽管Field 通过允许子类提供自己的validators 来定义可变性,但TextField 并没有明确扩展这种可变性。

我一直在努力寻找更多关于 LSP 的解释,但它们都重用了相同的 Rectangle/Square 示例。

给定:

def transmogulate(field):
    """field must be a TextField instance."""
    assert isinstance(field, TextField)
    instance.run_validators("hello")

使用CharField 时,transmogulate(my_text_field) 将毫无问题地运行。但是如果my_text_fieldEmailField 的一个实例,它总是会引发ValidationError。这是否违反了 LSP?还是我的推理完全倒退了? (这种情况经常发生)

您也可以愉快地想象run_validators() 返回False 而不是引发异常,如果这会以某种方式改变分析;我只是想让我的示例尽可能接近源材料。

【问题讨论】:

  • 只要有效,谁在乎?

标签: python oop theory liskov-substitution-principle


【解决方案1】:

我认为只要 EmailField 提供与 CharField 相同的方法(看起来确实如此),设计就可以了。如果它仍然像鸭子一样嘎嘎叫,它会跟随 LSP。子类可以有不同的实现或行为。

【讨论】:

  • 但是对于破坏 LSP 的常见 Rectangle/Square 示例也是如此。 Square 提供了相同的方法,所以它仍然像鸭子一样嘎嘎叫。但它的行为出乎意料,我认为这是导致它破坏 LSP 的原因。
  • 好点...我有兴趣听到其他答案。我认为它与矩形/正方形有点不同,因为据我所知,正方形的问题是 setHeight 和 setWidth 现在会做意想不到的事情。然而,在这种情况下, run_validators() 仍然只是告诉我们它是否有效,尽管逻辑略有不同。由于它是对用户数据进行操作,因此我认为这种行为差异不会影响现实世界中的程序员。
猜你喜欢
  • 2015-01-01
  • 2016-08-20
  • 2012-01-12
  • 1970-01-01
  • 2021-11-17
  • 1970-01-01
  • 2020-02-03
  • 1970-01-01
相关资源
最近更新 更多