版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、第五講:開閉原則與里氏替換原則,目錄,開放封閉原則(OCP) OCP編程實(shí)例 OCP原則實(shí)施要點(diǎn) Liskov替換原則 Liskov原則實(shí)施要點(diǎn) 總結(jié),開放封閉原則(OCP,什么是軟件開發(fā)過程中最不穩(wěn)定的因素? 答案是需求!需求在軟件開發(fā)過程中時(shí)時(shí)刻刻都可能發(fā)生變化。那么,如何靈活應(yīng)對變化是軟件結(jié)構(gòu)設(shè)計(jì)中最重要也是最困難的一個(gè)問題。好的設(shè)計(jì)帶來了極大了靈活性,不好的設(shè)計(jì)則充斥著僵化的臭味。所以我們要遵循開放封閉原則OCP,開放封閉原則(OCP,Bertrand Meyer,面向?qū)ο蠹夹g(shù)大師,發(fā)明了Eiffel 語言和按契約設(shè)計(jì)(Design by Contract)的思想,名著面向?qū)ο筌浖?gòu)造
2、的作者,法國工程院院士。目前,他除了擔(dān)任Eiffel環(huán)境和工具開發(fā)公司ISE的CTO之外,還是愛因斯坦的母校蘇黎世聯(lián)邦工學(xué)院計(jì)算機(jī)科學(xué)系教授,擔(dān)任軟件工程項(xiàng)目主席,同時(shí)還在澳大利亞Monash大學(xué)任教。他于1988年提出了著名的開放封閉原則(OCP,開放封閉原則的現(xiàn)實(shí)意義,開放封閉原則(OCP,Open Closed Principle)是所有面向?qū)ο笤瓌t的核心。軟件設(shè)計(jì)本身所追求的目標(biāo)就是封裝變化、降低耦合。而開放封閉原則正是對這一目標(biāo)的最直接體現(xiàn)。其他的設(shè)計(jì)原則,很多時(shí)候是為實(shí)現(xiàn)這一目標(biāo)服務(wù)的,例如后面將介紹的Liskov替換原則實(shí)現(xiàn)最佳的、正確的繼承層次,就能保證不會(huì)違反開放封閉原則。
3、OCP核心的思想是: 軟件實(shí)體應(yīng)該是可擴(kuò)展,而不可修改的。也就是說,對擴(kuò)展是開放的,而對修改是封閉的,OCP特征,軟件實(shí)體(類、模塊、函數(shù)等)應(yīng)該是可擴(kuò)展的,但是不可修改的。OCP有兩大特征: 對于擴(kuò)展是開放的(Open for extension) 模塊的行為可以擴(kuò)展,當(dāng)應(yīng)用的需求改變時(shí),可以對模塊進(jìn)行擴(kuò)展,以滿足新的需求。 對于更改是封閉的(Closed for modification) 對模塊行為擴(kuò)展時(shí),不必改動(dòng)模塊的源代碼或二進(jìn)制代碼,OCP的關(guān)鍵在于抽象,OCP的關(guān)鍵在于抽象 抽象技術(shù):abstract class, Interface 抽象預(yù)見了可能的所有擴(kuò)展(閉) 由抽象可以隨
4、時(shí)導(dǎo)出新的類(開,范例:手與門,如何在程序中模擬用手去開門和關(guān)門? 行為: 開門(open) 關(guān)門(close) 判斷門的狀態(tài)(isOpened,設(shè)計(jì)實(shí)現(xiàn),public class Door private boolean _isOpen=false; public boolean isOpen() return _isOpen; public void open() _isOpen = true; public void close() _isOpen = false;,public class Hand public Door door; void do() if (door.isOpen
5、() door.close(); else door.open();,public class SmartTest public static void main(String args) Hand myHand = new Hand(); myHand.door = new Door(); myHand.do();,新的需求,需要手去開關(guān)抽屜,冰箱,我們只好去修改程序,解決新的需求:修改設(shè)計(jì),public class Hand public Door door; public Drawer drawer; void do(int item) switch (item) case 1: if
6、(door.isOpen() door.close(); else door.open(); break; case 2: if (drawer.isOpen() drawer.close(); else drawer.open(); break;,public class SmartTest public static void main(String args) Hand myHand = new Hand(); myHand.door = new Door(); myHand.do(1);,手被改了! 主(使用手)程序也被改了,符合OCP的設(shè)計(jì)方案,public interface Ex
7、cutable public boolean isOpen(); public void open(); public void close();,新的實(shí)現(xiàn),public class Door implements Excutable private boolean _isOpen = false; public boolean isOpen() return _isOpen; public void open() _isOpen = true; public void close() _isOpen = false;,public class Hand public Excutable it
8、em; void do() if (item.isOpen() item.close(); else item.open();,public class Drawer implements Excutable private boolean _isOpen = false; public boolean isOpen() return _isOpen; public void open() _isOpen = true; public void close() _isOpen = false;,public class SmartTest public static void main(Str
9、ing args) Hand myHand = new Hand(); myHand.item = new Door(); myHand.do();,新的需求,需要手去開關(guān)冰箱,為冰箱實(shí)現(xiàn)Excutable接口 不需要修改任何原有的設(shè)計(jì)和代碼,public class Refrigerator implements Excutable private boolean _isOpen = false; public boolean isOpen() return _isOpen; public void open() _isOpen = true; public void close() _is
10、Open = false;,OCP原則實(shí)施要點(diǎn),預(yù)測變化和“貼切的”結(jié)構(gòu) 上述的例子其實(shí)并不是完全封閉的,如果手增加了新的動(dòng)作,例如搬運(yùn),很多地方還是會(huì)有改動(dòng)變化。那么原來所選定的抽象對于這種變化來說反到成為一種障礙。 一般而言,無論模塊是多么的“封閉”,都會(huì)存在一些無法對之封閉的變化。沒有對于所有的情況都貼切的模型。 設(shè)計(jì)人員必須對于他們設(shè)計(jì)的模塊應(yīng)該對哪種變化封閉做出選擇。 必須先猜測出最有可能發(fā)生的變化種類,然后構(gòu)造抽象來隔離變化,OCP原則實(shí)施要點(diǎn),要避免進(jìn)行多余的抽象 遵循OCP的代價(jià)也是昂貴的。創(chuàng)建正確的抽象是要花費(fèi)時(shí)間和精力的。同時(shí)這些抽象也增加了軟件的復(fù)雜性。因此,開閉原則很難
11、被完全實(shí)現(xiàn),只能在某些模塊、某種程度上、某個(gè)限度內(nèi)符合OCP的要求。所以可以說,OCP具有理想主義的色彩,是OOD的終極目標(biāo)。 在項(xiàng)目很緊張的情況下,一般只會(huì)對能百分之百預(yù)測到的變化經(jīng)行抽象,而且要是那種會(huì)經(jīng)常發(fā)生變化的部分才進(jìn)行抽象,OCP原則實(shí)施要點(diǎn),隔離變化的手段 1. “只受一次愚弄” 這意味著在我們最初編寫代碼時(shí),假設(shè)變化不會(huì)發(fā)生;當(dāng)變化發(fā)生時(shí),我們就創(chuàng)建抽象來隔離以后發(fā)生的同類變化。 2. 刺激變化。 我們首先編寫測試 我們使用很短的迭代周期進(jìn)行開發(fā)一個(gè)周期為幾天而不是幾周 我們在加入基礎(chǔ)結(jié)構(gòu)之前就開發(fā)特性,并且經(jīng)常性的把那些特性展示給涉眾 我們首先開發(fā)最重要的特性 盡早的、經(jīng)常的
12、發(fā)布軟件,Liskov替換原則(LSP,LSP(The Liskov Substitution Principle, Liskov替換原則) “若對于類型S的任一對象o1,均有類型T的對象o2存在,使得在T定義的所有程序P中,用o1替換o2之后,程序的行為不變,則S是T的子類型,如果在任何情況下,子類(或子類型)或?qū)崿F(xiàn)類與基類都是可以互換的,那么繼承的使用就是合適的。為了達(dá)到這一目標(biāo),子類不能添加任何父類沒有的附加約束 “子類對象必須可以替換父類對象,從問題開始,長方形與正方形 假如我們有一個(gè)類:長方形(Rectangle) 我們需要一個(gè)新的類,正方形(Square) 問:可否直接繼承長方形,
13、沒問題,因?yàn)閿?shù)學(xué)上正方形就是長方形的子類,開始設(shè)計(jì):正方形,public class Rectangle private int width; private int height; public void setWidth(int w) width = w; public int getWidth() return width; public void setHeight(int h) height = h; public int getHeight() return height;,public class Square extends Rectangle public void setW
14、idth(int w) super.setWidth (w); super.setHeight (w); public void setHeight(int h) super.setWidth (h); super.setHeight (h) ;,設(shè)計(jì)方案正確嗎,public static void resize(Rectangle r) while (r.getHeight() = r.getWidth() r.setHeight(r.getHeight() + 1); System.out.println(“Its OK.);,Rectangle r1 = new Rectangle();
15、 r1.setHeight(5); r1.setWidth(15); resize(r1,Rectangle r2 = new Square(); r2.setHeight(5); r2.setWidth(15); resize(r2,使用父類(長方形)時(shí),程序正常運(yùn)行 使用子類(正方形)時(shí),程序陷入死循環(huán) 設(shè)計(jì)出問題了?繼承出問題了,違背LSP原則,Square類針對height、width添加了Rectangle所沒有的附加的約束 違背了LSP原則 帶來潛在的設(shè)計(jì)問題(使用resize方法時(shí),子類出錯(cuò),怎么辦,在可能的情況下,由抽象類(接口)繼承,解決方案,IS-A關(guān)系的思考,鴕鳥是鳥嗎?
16、是 鴕鳥有翅膀,鳥也有翅膀 鴕鳥有喙,鳥也有喙 但是 鳥.getFlySpeed() 鴕鳥.getRunSpeed() 有著不同 結(jié)論:IS-A應(yīng)當(dāng)是關(guān)于行為的。 LSP清晰的指出,OOD中ISA關(guān)系是就行為方式而言的,行為方式是可以進(jìn)行合理假設(shè)的,是客戶程序所依賴的,IS-A關(guān)系的思考(續(xù),對于動(dòng)物學(xué)家 只關(guān)心鳥的生理特征,對他們來說,鴕鳥就是鳥 對于養(yǎng)鳥人 關(guān)心鳥的行為特征,鴕鳥不是鳥 他們都正確 考慮一個(gè)特定設(shè)計(jì)是否恰當(dāng)時(shí),不能完全孤立地看這個(gè)解決方案,應(yīng)該根據(jù)設(shè)計(jì)的使用者提出的合理假設(shè)來審視,抽象類與具體類,只要有可能,不要從具體類繼承。 行為集中的方向是向上的(抽象類) 數(shù)據(jù)集中的方
17、向是向下的(具體類,LSP原則實(shí)施要點(diǎn),一個(gè)模型,如果孤立的看,并不具有真正意義上的有效性。模型的有效性只能通過它的客戶程序來表現(xiàn)。 有誰知道設(shè)計(jì)的使用者會(huì)做出什么樣的合理假設(shè)呢?大多數(shù)這樣的假設(shè)都很難預(yù)測。事實(shí)上,如果試圖去預(yù)測所有這些假設(shè),我們所得到的系統(tǒng)很可能會(huì)充滿不必要的復(fù)雜性的臭味。 因此,像OCP原則一樣通常最好的辦法就是只預(yù)測那些最明顯的對于LSP的違反情況,而推遲所有其它的預(yù)測,直到出現(xiàn)相關(guān)的脆弱性的臭味時(shí),才去處理它們,LSP原則實(shí)施要點(diǎn),基于契約設(shè)計(jì) 基于契約設(shè)計(jì)(DBC:Design By Contract)。使用DBC,類的編寫者能夠顯式的規(guī)定針對該類的契約。客戶代碼的
18、編寫者可以通過該契約獲悉可以依賴的行為方式。契約是通過為每個(gè)方法聲明的前置條件(preconditions)和后置條件(postconditions)來指定的。要使一個(gè)方法得以執(zhí)行,前置條件必須要為真。執(zhí)行完畢后,該方法要保證后置條件為真,LSP原則實(shí)施要點(diǎn),在單元測試中指定契約 也可以通過編寫單元測試的方式來指定契約??蛻舸a編寫者會(huì)去查看這些單元測試,這樣他們就可以知道對于要使用的類,應(yīng)該做什么合理的假設(shè),LSP原則實(shí)施要點(diǎn),啟發(fā)式規(guī)則 1.派生類中的退化函數(shù) 在基類中實(shí)現(xiàn)了f()方法,在派生類中的函數(shù)f()就是退化的,派生類中的退化函數(shù)并不總表示為違反LSP,但是當(dāng)存在這種情況時(shí),還是值得注意一下的。 2.從派生類中拋出異常 在派生類的方法中添加了其基類不會(huì)拋出的異常。如果基類的使用者不期望這些異常,那么把它們添加到派生類的方法中就會(huì)導(dǎo)致不可替換性。此時(shí)要遵循LSP,要
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 繪畫心理治療課程-認(rèn)識你自己課件
- 2021全球多行業(yè)重大網(wǎng)絡(luò)安全事件大盤點(diǎn)
- 安全員年度再教育3
- 2025-2030全球自動(dòng)緊湊型視野計(jì)行業(yè)調(diào)研及趨勢分析報(bào)告
- 2025-2030全球商用蘑菇殺菌設(shè)備行業(yè)調(diào)研及趨勢分析報(bào)告
- 2025年全球及中國粘度過程分析儀行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報(bào)告
- 2025年全球及中國磨削數(shù)控系統(tǒng)行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報(bào)告
- 2025-2030全球水力冷凝鍋爐行業(yè)調(diào)研及趨勢分析報(bào)告
- 2025年全球及中國電動(dòng)甲板機(jī)械行業(yè)頭部企業(yè)市場占有率及排名調(diào)研報(bào)告
- 照明亮化工程施工合同
- 《梅大高速茶陽路段“5·1”塌方災(zāi)害調(diào)查評估報(bào)告》專題警示學(xué)習(xí)
- 2024年09月北京中信銀行北京分行社會(huì)招考(917)筆試歷年參考題庫附帶答案詳解
- 《大健康解讀》課件
- 2025年度交通運(yùn)輸規(guī)劃外聘專家咨詢協(xié)議3篇
- 2024年公司領(lǐng)導(dǎo)在新年動(dòng)員會(huì)上的講話樣本(3篇)
- 2025年中國濕度傳感器行業(yè)深度分析、投資前景、趨勢預(yù)測報(bào)告(智研咨詢)
- 人教版道德與法治二年級下冊《第一單元 讓我試試看》大單元整體教學(xué)設(shè)計(jì)2022課標(biāo)
- 聯(lián)合體三方協(xié)議合同模板
- 2024年3季度青島房地產(chǎn)市場季度簡報(bào)
- 蘇東坡詞十首
- 2023年天津市文化和旅游局直屬事業(yè)單位招聘考試真題及答案
評論
0/150
提交評論