[英]Liskov substitution principle and Streams
是否存在無法編寫或尋求的Stream派生類的事實是否打破了Liskov替換原則?
例如,無法搜索NetworkStream ,如果調用方法Seek
,它將拋出NotSupportedException
。
或者因為CanSeek
標志的存在它可以嗎?
考慮到Square
繼承自Rectangle
眾所周知的例子......將標志DoesHeightAffectsWidth
和DoesWidthAffectsHeight
到Rectangle
解決問題嗎?
這不是通過添加標志來打開固定東西的大門嗎?
CanSeek
技術上保持流類不違反LSP。 只有它返回真實,才會尋求工作的承諾。
我個人認為它是ISP的嚴重彎曲,可能是SRP,而我的內部設計師更喜歡像可搜索流可以繼承的SeekableStream
子類/接口。 但我確信這帶來了自己的問題(例如,在有時只能搜索的流中)......坦率地說,現實世界的可用性勝過原則。
這是要記住的事情。 偶爾,原則與現實相互碰撞。 在大多數情況下,SOLID原則有助於最大限度地減少不必要的復雜性,並且通常可以保持OO系統的可維護性並防止它們在自身重量下崩潰。 如果純度導致系統更復雜,但是 - 例如,因為現在只有有時可尋找的流不能很好地適應層次結構 - 那么偶爾的丑陋可能是合理的。
但它永遠不應該只是因為法律條文允許它的第一選擇。 SOLID原則不僅僅是規則; 他們是原則 。 他們是這些詞語背后的思想 - 法律的精神 。 如果你在通過精神律師的過程中堅持這封信,那么你就錯過了原則的全部要點。
至於Square / Rectangle問題......從技術上講,確定改變高度是否也會改變寬度的屬性/函數可以被認為與LSP的字母保持一致。 盡管如此,感覺就像律師一樣,並且正在推動其他SOLID原則的界限。 從現實的角度來看,它絕對不是最佳解決方案,因為它增加了復雜性並引入了偶然副作用的可能性; 現在一切都想說rect.Height = 50;
也可能無意中改變了寬度。
Can...
方法意味着Stream
不會破壞LSP。 Stream
提供了讀,寫和尋求的能力 ,但不能保證任何實現類將履行它。 Can...
方法使這成為Stream
契約的顯式特征 - 派生類必須實現它們以允許客戶端代碼在調用之前檢查派生類是否實現某些行為。 因此,任何嘗試寫入Stream
代碼都應該在調用Write
之前檢查CanWrite
,這可以通過任何正確實現的Stream
派生來完成。 因此,它們可以互換,因為LSP需要。
我認為添加標記派生類是否實現特定功能的方法肯定會被濫用 - 如果一個團隊沒有紀律,他們最終可能會有一個非常寬泛,臃腫的界面打破ISP。 我認為Stream
和IList<T>
在這方面設計得很好 - 它們不會破壞LSP,並且它們定義了一個足夠狹窄的密切相關行為的合同以留在ISP中。 顯然,他們的設計已經考慮過了。
我認為在Square
繼承Rectangle
的情況下,您當然可以添加DoesHeightAffectsWidth
和DoesWidthAffectsHeight
來解決問題,但是團隊必須決定是否可以接受,或者這些方法的添加是否會破壞ISP。 是否添加了AreAllInternalAnglesEqual
來支持梯形太遠? 在某種程度上,由編寫代碼的工程師決定。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.