如果字段> CharField> EmailField,EmailField是否使用CharField打破Liskov替换原则?

时间:2013-06-11 15:29:01

标签: python oop theory liskov-substitution-principle

假设我正在编写一个包含Form课程的网络应用,而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而不是提出异常,如果这会以某种方式改变分析;我只想让我的例子尽可能靠近源材料。

1 个答案:

答案 0 :(得分:0)

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