2013-06-11 71 views
1

假設我正在編寫一個Form類的webapp,並且Form類可以有幾個Fields如果Field> CharField> EmailField,EmailField是否打破Liskov與CharField的替代原則?

Field本身是一個抽象類。它包含一個抽象的validators屬性,它是一個方法列表,它將調用以確定該字段的內容是否有效。這些驗證器通過實例方法調用Field.run_validators(value)

CharField是一個允許任意文本的Field子類。這個字段總是有效的,只要給它一些非零長度的字符串即可。

EmailField是具有附加要求的CharField子類。此字段僅在value通過某種測試時有效。 (例如'@' in value)。

我的問題在於:EmailField相對於CharField打破了LSP嗎?它應該是兄弟會的班級嗎?儘管Field通過允許子類自己提供validators來定義可變性,但是TextField並未明確地擴展該可變性。

我一直試圖找到LSP的更多解釋,但它們都重複使用相同的矩形/方形示例。

考慮:

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

當使用CharFieldtransmogulate(my_text_field)將沒有問題運行。但是,如果my_text_fieldEmailField的實例,它將始終提高ValidationError。這是否違反LSP?或者我的推理完全倒退? (這經常發生)

你也可以像開心地想象run_validators()返回False而不是引發異常,如果這改變了分析,我只是想讓我的例子儘可能地接近原始資料。

+0

只要它工作誰關心? – clavio

回答

0

我認爲只要EmailField提供與CharField相同的方法(看起來好像它),設計就可以。如果它仍然像鴨子一樣嘎嘎叫,它會跟隨LSP。它可以讓子類具有不同的實現或行爲。

+0

但是,打破LSP的常見矩形/方形例子也是如此。 Square提供了相同的方法,所以它仍然像鴨子一樣嘎嘎。但它的行爲意外,我認爲是什麼導致它打破了LSP。 –

+1

好點...我有興趣聽到其他答案。我*認爲*它是有點不同於矩形/平方,雖然因爲我瞭解它的方形問題是setHeight和setWidth現在做了意想不到的事情。然而,在這種情況下,run_validators()仍然只是告訴我們它的有效或不是邏輯稍微不同。由於它是在用戶數據上運行的,我不認爲這種行爲差異會影響現實世界中的程序員。 – bwbrowning

相關問題