日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

当系统扩展遇到违背OO的里氏原则(LSP)的时候怎么办 ?

發(fā)布時間:2025/3/20 windows 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 当系统扩展遇到违背OO的里氏原则(LSP)的时候怎么办 ? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

先轉(zhuǎn)一篇寫得很好的文章:http://www.cnblogs.com/CodeGuy/archive/2012/03/26/2418803.html

==================================================================

OO的五大原則是指SRP、OCP、LSP、DIP、ISP。

SRP -- (Single Responsibility Principle 單一職責(zé)原則)

OCP——開閉原則(Closed for Modification; Open for Extension)

?

現(xiàn)將近期整理的文檔提供給大家,這里對LSP做重點的介紹,望對大家有幫助,在學(xué)習(xí)和使用OO設(shè)計的時候,我們應(yīng)該明白:OO的出現(xiàn)使得軟件工程師們能夠用更接近真實世界的方法描述軟件系統(tǒng)。然而,軟件畢竟是建立在抽象層次上的東西,再怎么接近真實,也不能替代真實或被真實替代。?
OO設(shè)計的五大原則之間并不是相互孤立的。彼此間存在著一定關(guān)聯(lián),一個可以是另一個原則的加強或是基礎(chǔ)。違反其中的某一個,可能同時違反了其余的原則。因此應(yīng)該把這些原則融會貫通,牢記在心!?
OO的五大原則是指SRP、OCP、LSP、DIP、ISP。?
1. SRP(Single Responsibility Principle 單一職責(zé)原則)?
單一職責(zé)很容易理解,也很容易實現(xiàn)。所謂單一職責(zé),就是一個設(shè)計元素只做一件事。什么是“只做一件事”?簡單說就是少管閑事。現(xiàn)實中就是如此,如果要你專心做一件事情,任何人都有信心可以做得很出色。?
OCP作為OO的高層原則,主張使用“抽象(Abstraction)”和“多態(tài)(Polymorphism)”將設(shè)計中的靜態(tài)結(jié)構(gòu)改為動態(tài)結(jié)構(gòu),維持設(shè)計的封閉性。?
2. OCP :開閉原則,很簡單,一句話:“Closed for Modification; Open for Extension”——“對變更關(guān)閉;對擴展開放”。開閉原則其實沒什么好講的,我將其歸結(jié)為一個高層次的設(shè)計總則。OCP的動機很簡單:軟件是變化的。不論是優(yōu)質(zhì)的設(shè)計還是低劣的設(shè)計都無法回避這一問題。OCP說明了軟件設(shè)計應(yīng)該盡可能地使架構(gòu)穩(wěn)定而又容易滿足不同的需求。 為什么要OCP?答案也很簡單——重用。?
3.LSP——里氏替換原則?
OCP作為OO的高層原則,主張使用“抽象(Abstraction)”和“多態(tài)(Polymorphism)”將設(shè)計中的靜態(tài)結(jié)構(gòu)改為動態(tài)結(jié)構(gòu),維持設(shè)計的封閉性“抽象”是語言提供的功能?!岸鄳B(tài)”由繼承語義實現(xiàn)。 如此,問題產(chǎn)生了:“我們?nèi)绾稳ザ攘坷^承關(guān)系的質(zhì)量?”?
Liskov于1987年提出了一個關(guān)于繼承的原則“Inheritance should ensure that any property proved about supertype objects also holds for subtype objects.”——“繼承必須確保超類所擁有的性質(zhì)在子類中仍然成立。”也就是說,當(dāng)一個子類的實例應(yīng)該能夠替換任何其超類的實例時,它們之間才具有is-A關(guān)系。?
該原則稱為Liskov Substitution Principle——里氏替換原則。?
我們來研究一下LSP的實質(zhì)。學(xué)習(xí)OO的時候,我們知道,一個對象是一組狀態(tài)和一系列行為的組合體。狀態(tài)是對象的內(nèi)在特性,行為是對象的外在特性。LSP所表述的就是在同一個繼承體系中的對象應(yīng)該有共同的行為特征。?
這一點上,表明了OO的繼承與日常生活中的繼承的本質(zhì)區(qū)別。舉一個例子:生物學(xué)的分類體系中把企鵝歸屬為鳥類。我們模仿這個體系,設(shè)計出這樣的類和關(guān)系。?


類“鳥”中有個方法fly,企鵝自然也繼承了這個方法,可是企鵝不能飛阿,于是,我們在企鵝的類中覆蓋了fly方法,告訴方法的調(diào)用者:企鵝是不會飛的。這完全符合常理。但是,這違反了LSP,企鵝是鳥的子類,可是企鵝卻不能飛!需要注意的是,此處的“鳥”已經(jīng)不再是生物學(xué)中的鳥了,它是軟件中的一個類、一個抽象。?
有人會說,企鵝不能飛很正常啊,而且這樣編寫代碼也能正常編譯,只要在使用這個類的客戶代碼中加一句判斷就行了。但是,這就是問題所在!首先,客戶代碼和“企鵝”的代碼很有可能不是同時設(shè)計的,在當(dāng)今軟件外包一層又一層的開發(fā)模式下,你甚至根本不知道兩個模塊的原產(chǎn)地是哪里,也就談不上去修改客戶代碼了??蛻舫绦蚝芸赡苁沁z留系統(tǒng)的一部分,很可能已經(jīng)不再維護,如果因為設(shè)計出這么一個“企鵝”而導(dǎo)致必須修改客戶代碼,誰應(yīng)該承擔(dān)這部分責(zé)任呢?(大概是上帝吧,誰叫他讓“企鵝”不能飛的。^_^)“修改客戶代碼”直接違反了OCP,這就是OCP的重要性。違反LSP將使既有的設(shè)計不能封閉!?

修正后的設(shè)計如下:?

LSP并沒有提供解決這個問題的方案,而只是提出了這么一個問題。 于是,工程師們開始關(guān)注如何確保對象的行為。1988年,B. Meyer提出了Design by Contract(契約式設(shè)計)理論。DbC從形式化方法中借鑒了一套確保對象行為和自身狀態(tài)的方法,其基本概念很簡單:?

每個方法調(diào)用之前,該方法應(yīng)該校驗傳入?yún)?shù)的正確性,只有正確才能執(zhí)行該方法,否則認(rèn)為調(diào)用方違反契約,不予執(zhí)行。這稱為前置條件(Pre-condition)。?
一旦通過前置條件的校驗,方法必須執(zhí)行,并且必須確保執(zhí)行結(jié)果符合契約,這稱之為后置條件(Post-condition)。?
對象本身有一套對自身狀態(tài)進行校驗的檢查條件,以確保該對象的本質(zhì)不發(fā)生改變,這稱之為不變式(Invariant)。
以上是單個對象的約束條件。為了滿足LSP,當(dāng)存在繼承關(guān)系時,子類中方法的前置條件必須與超類中被覆蓋的方法的前置條件相同或者更寬松;而子類中方法的后置條件必須與超類中被覆蓋的方法的后置條件相同或者更為嚴(yán)格。?

4.DIP 依賴倒置原則?
依賴倒置(Dependence Inversion Principle)原則講的是:要依賴于抽象,不要依賴于具體。?
簡單的說,依賴倒置原則要求客戶端依賴于抽象耦合。原則表述:?
抽象不應(yīng)當(dāng)依賴于細(xì)節(jié);細(xì)節(jié)應(yīng)當(dāng)依賴于抽象;?
要針對接口編程,不針對實現(xiàn)編程。?

5.ISP 接口隔離原則?
使用多個專門的接口比使用單一的總接口要好。廣義的接口:一個接口相當(dāng)于劇本中的一種角色,而此角色在一個舞臺上由哪一個演員來演則相當(dāng)于接口的實現(xiàn)。因此一個接口應(yīng)當(dāng)簡單的代表一個角色,而不是一個角色。,如果系統(tǒng)設(shè)計多個角色的話,則應(yīng)當(dāng)每一個角色都由一個特定的接口代表。狹義的接口(Interface):接口隔離原則講的就是同一個角色提供寬、窄不同的接口,以對付不同的客戶端。 ============================================================================ 文中舉例企鵝繼承鳥這個問題,我覺得很有意思。確實如果鳥類中有fly()這個方法, 如果企鵝去繼承了, 必然會飛不起來,鴕鳥也一樣。但是我覺得到底企鵝能不能繼承鳥類, 完全取決于對“鳥”的定義, 如果在應(yīng)用中定義的“鳥”一定是會飛得起來的鳥, 那企鵝,鴕鳥肯定不能繼承, 因為它們雖然都有翅膀, 但卻都飛不起來。那問題出在哪里? 應(yīng)該如何解決這個問題? 不能簡單下結(jié)論,完全取決于應(yīng)該本身的需求。 如果把系統(tǒng)當(dāng)作一個鳥的樂園: 1. 最開始由于樂園里面的鳥都會飛, 所以基類“鳥”都有fly()方法。 2. 突然有一天,樂園領(lǐng)導(dǎo)讓新鳥引進部門引進新的鳥進來,辦事員由于不知道企鵝不會飛, 結(jié)果他把企鵝給收了,相當(dāng)于企鵝繼承了鳥這個類, 自然就有了fly()方法。 但企鵝卻不會飛,于是乎,鳥樂園里面就有了一只不會飛的企鵝。 3. 那問題出在哪里? 有幾種可能 1)辦事員辦事不力, 本來不該引進企鵝, 結(jié)果由于知識缺乏,錯誤的引進了不會飛的企鵝。這個BUG的根源就是“新鳥引進部門”的錯誤導(dǎo)致的。 2)同時, 雖然“新鳥引進部門”有問題,但原來樂園的名字也有問題,既然只能養(yǎng)會飛的鳥,那樂園名字就不該叫鳥樂園,而該叫”飛鳥樂園“, 樂園里面所有鳥的基類也應(yīng)該叫”飛鳥“, 而不是”鳥“。 3)鳥樂園本來就有不會飛的鳥,里面原來就有養(yǎng)鴕鳥,引入不會飛的企鵝完全沒有問題。那么這個問題其實就是鳥這個基類定義錯了, fly()這個方法本來就不該出現(xiàn)在“鳥”這個基類里面。 4)鳥樂園原來確實只有會飛的鳥,但名字也沒錯,雖然現(xiàn)在全是會飛的鳥,但樂園領(lǐng)導(dǎo)最初的想法就是為了以后啥鳥都養(yǎng)。那現(xiàn)在引入企鵝后應(yīng)該咋辦呢, 就需要對系統(tǒng)做適當(dāng)?shù)闹貥?gòu),先把目前的"鳥"這個基類改名成“會飛的鳥”, 然后再構(gòu)建一個“不會飛的鳥”, 里面沒有fly()方法,在從飛“不會飛的鳥中”繼承產(chǎn)生“企鵝”類。原來的“鳥”類去掉fly()方法,新的“會飛的鳥”與“不會飛的鳥”都可以繼承自新定義的“鳥"類。

轉(zhuǎn)載于:https://www.cnblogs.com/chry/p/7125946.html

總結(jié)

以上是生活随笔為你收集整理的当系统扩展遇到违背OO的里氏原则(LSP)的时候怎么办 ?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。