




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、設(shè)計(jì)模式和代碼重構(gòu)什么是優(yōu)秀的設(shè)計(jì)抗拒變化是無用的他們不知道自己需要什么,因此也無法提出要求他們知道自己需要什么,但不知道如何說明它他們能夠說明,但我們誤解了他們我們理解了,但漏掉了隱含的意義、優(yōu)先級(jí)或細(xì)節(jié)所有這一切都沒問題,但市場總會(huì)變化軟件需求變更法則 軟件不斷變更法則:真實(shí)世界中使用的程序必須進(jìn)行變更,否則它在環(huán)境中的作用就會(huì)越來越小.敏捷思想最大的貢獻(xiàn)-1對軟件需求變化的態(tài)度傳統(tǒng)工程學(xué)里有一個(gè)基本假設(shè)是,需要對未來有很詳細(xì)的計(jì)劃和預(yù)測,有清晰的進(jìn)度和流程。但其實(shí)軟件開發(fā)非常不同,它包含很多藝術(shù)的成分,人的創(chuàng)造力至關(guān)重要,而且軟件的需求非常易變。而敏捷對預(yù)測未來的方式是全新的,強(qiáng)調(diào)通過提
2、高團(tuán)隊(duì)的能力、設(shè)計(jì)的彈性和流程的靈活性來適應(yīng)變化。這種思路對軟件開發(fā)也是很大的沖擊。案例分析-1需求描述 客戶名稱:影片租賃連鎖企業(yè) 統(tǒng)名稱:影片租賃管理系統(tǒng) 需求描述: 1:完成影片連鎖企業(yè)租賃管理系統(tǒng), 可以計(jì)算每一位客戶的消費(fèi)金額和影片的詳細(xì)信息,金額根據(jù)影片的類型和租賃的日期來進(jìn)行計(jì)算. 2:客戶把影片分成3類進(jìn)行管理 A:最新電影 B:普通電影 C:兒童影片. 3:費(fèi)用計(jì)算規(guī)則如下 a:是普通電影,如果租期小于2天,費(fèi)用為2元錢.如果租期大于兩天,費(fèi)用是租期減去2,每天1.5元 b:如果是新片電影,費(fèi)用為每天3元 c:是兒童電影,如果租期小于3天,費(fèi)用為1.5元錢.如果租期大于三天,
3、費(fèi)用是租期減去3,每天1.5元 4:每次客戶租賃電影可以為客戶積累積分,規(guī)則是每次累計(jì)增加1分. 如果是新片,并且租期大于1天,再增加一分 5:暫且不要考慮系統(tǒng)界面問題和系統(tǒng)的存儲(chǔ)問題總結(jié) 增加一個(gè)功能特性的成本并不單單是為這些功能編碼所花費(fèi)時(shí)間的成本,還應(yīng)該包括特性擴(kuò)展的障礙成本。什么是好的設(shè)計(jì) 一個(gè)好的系統(tǒng)設(shè)計(jì)應(yīng)該有如下的性質(zhì):可擴(kuò)展性、靈活性、可插入性。 好的設(shè)計(jì)的目標(biāo) 可擴(kuò)展性(Extensibility): 新的功能可以很容易地加入到系統(tǒng)之中,這就是可擴(kuò)展性. 靈活性(Flexiblity) :可以容許代碼修改平穩(wěn),而不會(huì)波及到很多其他的模塊.這就是靈活性 可插入性(Pluggabi
4、lity) :可以很容易地將一個(gè)類抽出去,同時(shí)將另一個(gè)有同樣接口的類加入進(jìn)來.這就是可插入性.開放封閉原則(OCP) 軟件組成實(shí)體(類,模塊,函數(shù),等等)應(yīng)該是可擴(kuò)展的,但是不可修改的。 即軟件實(shí)體可以通過增加新代碼實(shí)現(xiàn)擴(kuò)展,但是不能修改已有的代碼 任何系統(tǒng)在其生命周期中都會(huì)發(fā)生變化。如果我們希望開發(fā)出的系統(tǒng)不會(huì)在第一版本后就被拋棄,那么我們就必須牢牢記住這一點(diǎn)。優(yōu)秀設(shè)計(jì) 發(fā)現(xiàn)變化/封裝變化 隔離變化 動(dòng)態(tài)綁定 解耦具體依賴適應(yīng)變化 好的程序設(shè)計(jì)所面臨的最主要的挑戰(zhàn)之一就是適應(yīng)變化.設(shè)計(jì)原則1:發(fā)現(xiàn)變化,封裝變化:發(fā)現(xiàn)變化,封裝變化 找出應(yīng)用中可能需要變化之處,把它們獨(dú)立出來,不要和那些不需要
5、變化的代碼混在一起. 實(shí)現(xiàn):把會(huì)變化的部分取出并封裝起來,以便以后可以輕易地改動(dòng)和擴(kuò)充此部分,而不影響不需要變化的其他部分.抽象穩(wěn)定接口設(shè)計(jì)設(shè)計(jì)原則2:抽象穩(wěn)定接口,針對接口:抽象穩(wěn)定接口,針對接口 抽象接口:創(chuàng)建出固定卻能描述一組任意個(gè)可能行為的抽象體,這個(gè)抽象就像抽象基類或者接口,任意個(gè)可能的行為就是可能的派生類. 針對接口(抽象)設(shè)計(jì):由于模塊子間依賴一個(gè)固定的抽象,所以它對于更改可以是關(guān)閉的.設(shè)計(jì)原則3:分離變化維度,單一職責(zé)原則:分離變化維度,單一職責(zé)原則 單一原則:就一個(gè)類而言,應(yīng)該僅有一個(gè)引起它變化的原因. 職責(zé)定義為 “變化的原因(a reason for change)”,如
6、果你能夠想到多于一個(gè)的動(dòng)機(jī)去改變一個(gè)類,那么這個(gè)類就具有多于一個(gè)的職責(zé).靜態(tài)綁定 與 動(dòng)態(tài)綁定 代碼結(jié)構(gòu)在編譯時(shí)刻就被確定下來了,比如它由繼承關(guān)系固定的類組成,或者硬編碼實(shí)現(xiàn)等。 而程序的運(yùn)行時(shí)刻結(jié)構(gòu)是由快速變化的對象實(shí)現(xiàn)。編譯時(shí)兩個(gè)結(jié)構(gòu)是彼此獨(dú)立的。蠟筆(粗細(xì)的變化和顏色的變化,靜態(tài)綁定)畫筆(粗細(xì)的變化和顏色的變化,分離,動(dòng)態(tài)綁定)設(shè)計(jì)原則4:盡量動(dòng)態(tài)綁定,組合:盡量動(dòng)態(tài)綁定,組合/聚合復(fù)用原則聚合復(fù)用原則 盡量的使用合成和聚合,而不是繼承關(guān)系達(dá)到復(fù)用的目的。 該原則就是在一個(gè)新的對象里面使用一些已有的對象,使之成為新對象的一部分:新的對象通過向這些對象的委派達(dá)到復(fù)用已有功能的目的。多態(tài)與
7、繼承 繼承是多態(tài)的基礎(chǔ),多態(tài)是繼承的目的! NM PK N+M解耦具體依賴 4種方式 配置文件與反射技術(shù) 表驅(qū)動(dòng)法 慣例優(yōu)于配置 依賴注入方案1-配置文件與反射技術(shù) 將反射技術(shù)與配置文件結(jié)合,在具體對象擁有共同抽象的前提下,通過配置文件獲得具體的對象類型,然后利用反射創(chuàng)建相應(yīng)對象.必須知道的設(shè)計(jì)法則 找出應(yīng)用中可能需要變化之處,把它們獨(dú)立出來,不要和那些不需要變化的代碼交織在一起. 抽象穩(wěn)定接口(抽象類),針對接口編程,而不是針對實(shí)現(xiàn)編程 分離變化維度,單一職責(zé)原則 動(dòng)態(tài)綁定還是靜態(tài)綁定,多用組合,少用繼承 創(chuàng)建與使用分離,創(chuàng)建有變化也要封裝面向?qū)ο笤O(shè)計(jì)原則開閉原則 一個(gè)設(shè)計(jì)良好的應(yīng)用程序應(yīng)該
8、充分考慮到開發(fā)和維護(hù)階段需求的頻繁變化,通常情況下,添加一個(gè)新的功能需要做出很多修改,我們應(yīng)該使對已有代碼的修改最小化,因?yàn)樗麄円呀?jīng)經(jīng)過了測試。對現(xiàn)有代碼做出修改將會(huì)以一種不可預(yù)料的方式影響它們的已有功能。 一個(gè)軟件實(shí)體應(yīng)該對擴(kuò)展開發(fā),對修改關(guān)閉。開閉原則是說我們應(yīng)該努力設(shè)計(jì)不需要修改的模塊。在擴(kuò)展系統(tǒng)的行為時(shí),我們只需要添加新的代碼,而不需要修改已有的代碼。一般可以通過添加新的子類和重寫父類的方法來實(shí)現(xiàn)。開閉原則 滿足開閉原則的模塊符合下面兩個(gè)標(biāo)準(zhǔn): 對擴(kuò)展開放- 模塊的行為可以被擴(kuò)展從而滿足新的需求。 對修改關(guān)閉- 不允許修改模塊的源代碼。(或者盡量使修改最小化) 怎樣實(shí)現(xiàn)開閉原則 抽象、
9、接口、多態(tài)、繼承 要想使一個(gè)軟件系統(tǒng)的所有模塊都滿足開閉原則是不太現(xiàn)實(shí)的,不過我們應(yīng)該努力使大部分模塊滿足開閉原則。開閉原則是面向?qū)ο笤O(shè)計(jì)的核心,滿足該原則可以達(dá)到最大限度的復(fù)用和可維護(hù)性。開閉原則 實(shí)例 總結(jié) 像許多其他原則一樣,開閉原則只是面向?qū)ο笤O(shè)計(jì)的一個(gè)原則,實(shí)現(xiàn)一個(gè)靈活的設(shè)計(jì)需要額外的時(shí)間和努力,引入新的抽象層會(huì)增加代碼的復(fù)雜性。因此,該原則適用于那些需求會(huì)經(jīng)常發(fā)生變化的系統(tǒng)。有許多設(shè)計(jì)模式可以幫助我們擴(kuò)展功能而不需要修改代碼。例如,裝飾模式等。單一原則 在本文中職責(zé)是指引起變化的原因。該原則表明,如果你有多個(gè)原因去改變一個(gè)類,那么應(yīng)該把這些引起變化的原因分離開,把這個(gè)類分成多個(gè)類,
10、每個(gè)類只負(fù)責(zé)處理一種改變。當(dāng)你做出某種改變時(shí),只需要修改負(fù)責(zé)處理該改變的類。當(dāng)我們?nèi)ジ淖円粋€(gè)具有多個(gè)職責(zé)的類時(shí)可能會(huì)影響該類的其他功能 一個(gè)類應(yīng)該只受一種變化的影響。 單一職責(zé)原則簡單而直觀,但是在實(shí)際實(shí)現(xiàn)中可能是很困難的。單一原則 實(shí)例 總結(jié) 單一職責(zé)原則代表了設(shè)計(jì)應(yīng)用程序時(shí)一種很好的識(shí)別類的方式,并且它提醒你思考一個(gè)類的所有演化方式。只有對應(yīng)用程序的工作方式有了很好的理解,才能很好的分離職責(zé)。接口隔離原則 當(dāng)我們設(shè)計(jì)應(yīng)用程序的時(shí)候,如果一個(gè)模塊包含多個(gè)子模塊,那么我們應(yīng)該小心對該模塊做出抽象。設(shè)想該模塊由一個(gè)類實(shí)現(xiàn),我們可以把系統(tǒng)抽象成一個(gè)接口。但是當(dāng)我們想要添加一個(gè)新的模塊擴(kuò)展程序時(shí),如
11、果要添加的模塊只包含原系統(tǒng)中的一些子模塊,那么就會(huì)強(qiáng)迫我們實(shí)現(xiàn)接口中的所有方法,并且還要編寫一些啞方法。這樣的接口被稱為胖接口或者叫被污染的接口,使用這樣的接口將會(huì)給系統(tǒng)引入一些不正確的行為。 接口隔離原則表明客戶端不應(yīng)該被強(qiáng)迫實(shí)現(xiàn)一些他們不會(huì)使用的接口,應(yīng)該把胖接口中的方法分組,然后用多個(gè)接口代替它,每個(gè)接口服務(wù)于一個(gè)子模塊。 不應(yīng)該強(qiáng)迫客戶端依賴于他們不會(huì)使用的接口。接口隔離原則 實(shí)例 總結(jié) 如果已經(jīng)設(shè)計(jì)成了胖接口,可以使用適配器模式隔離它。像其他設(shè)計(jì)原則一樣,接口隔離原則需要額外的時(shí)間和努力,并且會(huì)增加代碼的復(fù)雜性,但是可以產(chǎn)生更靈活的設(shè)計(jì)。如果我們過度的使用它將會(huì)產(chǎn)生大量的包含單一方法
12、的接口,所以需要根據(jù)經(jīng)驗(yàn)并且識(shí)別出那些將來需要擴(kuò)展的代碼來使用它里氏代換原則 當(dāng)我們設(shè)計(jì)程序模塊時(shí),我們會(huì)創(chuàng)建一些類層次結(jié)構(gòu),然后我們通過擴(kuò)展一些類來創(chuàng)建它們的子類。我們必須確保子類只是擴(kuò)展而沒有替換父類的功能,否則當(dāng)我們在已有程序模塊中使用它們時(shí)將會(huì)產(chǎn)生不可預(yù)料的結(jié)果。里氏代換原則表明當(dāng)一個(gè)程序模塊使用基類時(shí),基類的引用可以被子類替換而不影響模塊的功能。 基類完全能夠被子類替代而不影響模塊的功能。里氏代換原則 實(shí)例 總結(jié) 里氏代換原則是對開閉原則的擴(kuò)展,它表明我們在創(chuàng)建基類的新的子類時(shí),不應(yīng)該改變基類的行為。依賴倒轉(zhuǎn)原則在一個(gè)應(yīng)用程序中,我們有一些實(shí)現(xiàn)了基礎(chǔ)的、主要的操作的底層類和一些封裝了
13、復(fù)雜邏輯的上層類。實(shí)現(xiàn)這種結(jié)構(gòu)的很自然地方式就是,先編寫底層類,完成后再編寫復(fù)雜的上層類。因?yàn)樯蠈宇愂怯善渌麞|西定義的,所以這看起來是一種很合理的方式。但是這不是一個(gè)靈活的設(shè)計(jì),如果我們需要替換一個(gè)底層類時(shí)會(huì)發(fā)生什么?讓我們以經(jīng)典的拷貝程序?yàn)槔?,它從鍵盤讀取一些字符,然后把他們輸出到打印設(shè)備上。包含該邏輯的上層類是Copy 類,底層類是KeyboardReader 和PrinterWriter。在一個(gè)不好的設(shè)計(jì)中,上層類直接使用底層的類,在這種情況下,如果我們想要把輸出定向到新的FileWriter 類,就必須修改Copy 類的代碼(假設(shè)它是一個(gè)具有很多邏輯的復(fù)雜類并且很難測試)。為了避免這種
14、問題,我們可以在上層類和底層類之間引入一個(gè)抽象層。因?yàn)樯蠈幽K包含復(fù)雜的邏輯,所以它們不應(yīng)該依賴于底層模塊,新的抽象層也不應(yīng)該基于底層模塊而創(chuàng)建。底層模塊應(yīng)該基于抽象層而創(chuàng)建?;谶@個(gè)原則,設(shè)計(jì)類結(jié)構(gòu)的方式應(yīng)該是從上層模塊到底層模塊。上層類-抽象層-底層類依賴倒轉(zhuǎn)原則 上層模塊不應(yīng)該依賴于底層模塊,它們都應(yīng)該依賴于抽象。 抽象不應(yīng)該依賴于細(xì)節(jié),細(xì)節(jié)應(yīng)該依賴于抽象。依賴倒轉(zhuǎn)原則 實(shí)例 總結(jié) 應(yīng)用該原則意味著上層類不直接使用底層類,他們使用接口作為抽象層。這種情況下上層類中創(chuàng)建底層類的對象的代碼不能直接使用new 操作符??梢允褂靡恍﹦?chuàng)建型設(shè)計(jì)模式,例如工廠方法,抽象工廠和原型模式。模版設(shè)計(jì)模式是
15、應(yīng)用依賴倒轉(zhuǎn)原則的一個(gè)例子。當(dāng)然,使用該模式需要額外的努力和更復(fù)雜的代碼,不過可以帶來更靈活的設(shè)計(jì)。不應(yīng)該隨意使用該原則,如果我們有一個(gè)類的功能很有可能在將來不會(huì)改變,那么我們就不需要使用該原則。迪米特法則迪米特法則(Law of Demeter)又叫最少知識(shí)原(Least Knowledge Principle LKP),就是說一個(gè)對象應(yīng)當(dāng)對其他對象有盡可能少的了解,不和陌生人說話對面向?qū)ο髞碚f,一個(gè)軟件實(shí)體應(yīng)當(dāng)盡可能的少的與其他實(shí)體發(fā)生相互作用。每一個(gè)軟件單位對其他的單位都只有最少的知識(shí),而其局限于那些與本單位密切相關(guān)的軟件單位。迪米特法則的目的在于降低類之間的耦合。由于每個(gè)類盡量減少對其
16、他類的依賴,因此,很容易使得系統(tǒng)的功能模塊相互獨(dú)立,相互之間不存在依賴關(guān)系。應(yīng)用迪米特法則有可能造成的一個(gè)后果就是,系統(tǒng)中存在的大量的中介類,這些類只所以存在完全是為了傳遞類之間的相互調(diào)用關(guān)系-這在一定程度上增加系統(tǒng)的復(fù)雜度。迪米特法則設(shè)計(jì)模式中的門面模式(Facade)和中介模式(Mediator)都是迪米特法則的應(yīng)用的例子。狹義的迪米特法則的缺點(diǎn):在系統(tǒng)里面造出大量的小方法,這些方法僅僅是傳遞間接的調(diào)用,與系統(tǒng)的商業(yè)邏輯無關(guān)。遵循類之間的迪米特法則會(huì)使一個(gè)系統(tǒng)的局部設(shè)計(jì)簡化,因?yàn)槊恳粋€(gè)局部都不會(huì)和遠(yuǎn)距離的對象有之間的關(guān)聯(lián)。但是,這也會(huì)造成系統(tǒng)的不同模塊之間的通信效率降低,也會(huì)使系統(tǒng)的不同模
17、塊之間不容易協(xié)調(diào)。廣義的迪米特法則在類的設(shè)計(jì)上的體現(xiàn):優(yōu)先考慮將一個(gè)類設(shè)置成不變類.盡量降低一個(gè)類的訪問權(quán)限。盡量降低成員的訪問權(quán)限。 案例組合/聚集復(fù)用原則 組合/聚合復(fù)用原則(Composite/Aggregate Reuse Principle CARP).組合和聚合都是對象建模中關(guān)聯(lián)(Association)關(guān)系的一種.聚合表示整體與部分的關(guān)系,表示“含有”,整體由部分組合而成,部分可以脫離整體作為一個(gè)獨(dú)立的個(gè)體存在。組合則是一種更強(qiáng)的聚合,部分組成整體,而且不可分割,部分不能脫離整體而單獨(dú)存在。在合成關(guān)系中,部分和整體的生命周期一樣,組合的新的對象完全支配其組成部分,包括他們的創(chuàng)建和
18、銷毀。一個(gè)合成關(guān)系中成分對象是不能與另外一個(gè)合成關(guān)系共享。 組合/聚合和繼承是實(shí)現(xiàn)復(fù)用的兩個(gè)基本途徑。合成復(fù)用原則是指盡量使用合成/聚合,而不是使用繼承。組合/聚集復(fù)用原則 只有當(dāng)以下的條件全部被滿足時(shí),才應(yīng)當(dāng)使用繼承關(guān)系。 子類是超類的一個(gè)特殊種類,而不是超類的一個(gè)角色,也就是區(qū)分“Has-A”和“Is-A”.只有“Is-A”關(guān)系才符合繼承關(guān)系,“Has-A”關(guān)系應(yīng)當(dāng)使用聚合來描述。 永遠(yuǎn)不會(huì)出現(xiàn)需要將子類換成另外一個(gè)類的子類的情況。如果不能肯定將來是否會(huì)變成另外一個(gè)子類的話,就不要使用繼承。3 子類具有擴(kuò)展超類的責(zé)任,而不是具有置換掉或注銷掉超類的責(zé)任。如果一個(gè)子類需要大量的置換掉超類的行
19、為,那么這個(gè)類就不應(yīng)該是這個(gè)超類的子類。 錯(cuò)誤的使用繼承而不是合成/聚合的一個(gè)常見原因是錯(cuò)誤地把“Has-A”當(dāng)成了“Is-A”.”Is-A”代表一個(gè)類是另外一個(gè)類的一種;而“Has-A”代表一個(gè)類是另外一個(gè)類的一個(gè)角色,而不是另外一個(gè)類的特殊種類。面向?qū)ο笤O(shè)計(jì)原則連連看面向?qū)ο蟮脑O(shè)計(jì)模式創(chuàng)建型模式 工廠模式 抽象工廠 單例 原型 構(gòu)建者The Factory Pattern Factory是最常見的設(shè)計(jì)模式之一,可幫助我們組織創(chuàng)建對象的代碼,通常用于以下兩種情況:v 創(chuàng)建復(fù)雜的對象,并進(jìn)行初始化。v 根據(jù)不同的環(huán)境(輸入?yún)?shù)),創(chuàng)建不同用途的對象。一般這些對象都是實(shí)現(xiàn)了相同的接口或繼承于同一
20、基類。Factory模式的JDBC應(yīng)用OracleDataSource負(fù)責(zé)創(chuàng)建鏈接,由函數(shù)getConnection獲取鏈接Factory模式應(yīng)用于DAO XMLDB是XML數(shù)據(jù)庫訪問接口,針對Oracle和DB2分別提供了實(shí)現(xiàn)。XMLDB_DAOFactory為類工廠,根據(jù)輸入的參數(shù)dbtype,創(chuàng)建不同的XMLDB實(shí)現(xiàn)類。更多的Factory模式應(yīng)用例子 Hibernate的SessionFactory,將數(shù)據(jù)庫表和對象的映射關(guān)系寫入XML格式的配置文件,然后由SessionFactory根據(jù)它來創(chuàng)建Session。 EJB容器本身就是一個(gè)EJB的Factory。當(dāng)客戶端調(diào)用EJB的時(shí)候,
21、由容器創(chuàng)建EJB供其使用。抽象工廠模式抽象工廠模式 抽象工廠模式(別名:配套) 提供一個(gè)創(chuàng)建一系列(相互依賴)對象的接口,而無需指定它們具體的類。Abstract Factory Pattern(Another Name:Kit) Provide an interface for creating families of related or dependent objects without specifying their concrete classes.一一 、 概述概述 當(dāng)系統(tǒng)準(zhǔn)備為用戶提供一系列相關(guān)的對象,又不想讓用戶代碼和創(chuàng)建這些對象的類形成耦合時(shí),就可以使用抽象工廠方法模式來設(shè)
22、計(jì)系統(tǒng)。抽象工廠模式的關(guān)鍵是在一個(gè)抽象類或接口中定義若干個(gè)抽象方法,這些抽象方法分別返回某個(gè)類的實(shí)例,該抽象類或接口讓其子類或?qū)崿F(xiàn)該接口的類重寫這些抽象方法,為用戶提供一系列相關(guān)的對象。 一一 、一一個(gè)實(shí)例個(gè)實(shí)例 建立一個(gè)系統(tǒng),該系統(tǒng)可以為用戶提供西服套裝(上衣褲子)和牛仔套裝(上衣褲子)。二、二、抽象工廠模式的結(jié)構(gòu)與使用抽象工廠模式的結(jié)構(gòu)與使用模式的結(jié)構(gòu)中包括四種角色:抽象產(chǎn)品(Prodcut) 具體產(chǎn)品(ConcreteProduct) 抽象工廠(AbstractFactory) 具體工廠(ConcreteFactory) 模式的UML類圖 模式的結(jié)構(gòu)的描述與使用 1抽象產(chǎn)品(Produc
23、t) :UpperClothes.javapublic abstract class UpperClothes public abstract int getChestSize(); public abstract int getHeight(); public abstract String getName(); Trousers.javapublic abstract class Trousers public abstract int getWaistSize(); public abstract int getHeight(); public abstract String getNa
24、me(); 模式的結(jié)構(gòu)的描述與使用 2具體產(chǎn)品(ConcreteProduct)_1: WesternUpperClothes.java public class WesternUpperClothes extends UpperClothes private int chestSize; private int height; private String name; WesternUpperClothes(String name,int chestSize,int height) =name; this.chestSize=chestSize; this.height=h
25、eight; public int getChestSize() return chestSize; public int getHeight() return height; public String getName() return name; 模式的結(jié)構(gòu)的描述與使用 2具體產(chǎn)品(ConcreteProduct)_2: CowboyUpperClothes.java public class CowboyUpperClothes extends UpperClothes private int chestSize; private int height; private String n
26、ame; CowboyUpperClothes(String name,int chestSize,int height) =name; this.chestSize=chestSize; this.height=height; public int getChestSize() return chestSize; public int getHeight() return height; public String getName() return name; 模式的結(jié)構(gòu)的描述與使用 2具體產(chǎn)品(ConcreteProduct)_3: WesternTrousers.jav
27、a public class WesternTrousers extends Trousers private int waistSize; private int height; private String name; WesternTrousers(String name,int waistSize,int height) =name; this.waistSize=waistSize; this.height=height; public int getWaistSize() return waistSize; public int getHeight() retur
28、n height; public String getName() return name; 模式的結(jié)構(gòu)的描述與使用 2具體產(chǎn)品(ConcreteProduct)_4: CowboyTrousers.java public class CowboyTrousers extends Trousers private int waistSize; private int height; private String name; CowboyTrousers(String name,int waistSize,int height) =name; this.waistSize=wa
29、istSize; this.height=height; public int getWaistSize() return waistSize; public int getHeight() return height; public String getName() return name; 模式的結(jié)構(gòu)的描述與使用 3抽象工廠(AbstractFactory):ClothesFactory.java public abstract class ClothesFactory public abstract UpperClothes createUpperClothes(int chestSiz
30、e,int height); public abstract Trousers createTrousers(int waistSize,int height);模式的結(jié)構(gòu)的描述與使用 4具體工廠(ConcreteFactory):BeijingClothesFactory.javapublic class BeijingClothesFactory extends ClothesFactory public UpperClothes createUpperClothes(int chestSize,int height) return new WesternUpperClothes(北京牌西
31、服上衣,chestSize,height); public Trousers createTrousers(int waistSize,int height) return new WesternTrousers(北京牌西服褲子,waistSize,height); ShanghaiClothesFactory.javapublic class ShanghaiClothesFactory extends ClothesFactory public UpperClothes createUpperClothes(int chestSize,int height) return new West
32、ernUpperClothes(上海牌牛仔上衣,chestSize,height); public Trousers createTrousers(int waistSize,int height) return new WesternTrousers(上海牌牛仔褲,waistSize,height); 模式的結(jié)構(gòu)的描述與使用 5應(yīng)用_1: Shop.java public class Shop UpperClothes cloth; Trousers trouser; public void giveSuit(ClothesFactory factory,int chestSize,int
33、waistSize,int height) cloth=factory.createUpperClothes(chestSize,height); trouser=factory.createTrousers(waistSize,height); showMess(); private void showMess() System.out.println(); System.out.println(cloth.getName()+:); System.out.print(胸圍:+cloth.getChestSize(); System.out.println(身高:+cloth.getHeig
34、ht(); System.out.println(trouser.getName()+:); System.out.print(腰圍:+trouser.getWaistSize(); System.out.println(身高:+trouser.getHeight(); 模式的結(jié)構(gòu)的描述與使用 5應(yīng)用_2: Application.java public class Application public static void main(String args) Shop shop=new Shop(); ClothesFactory factory=new BeijingClothesFac
35、tory(); shop.giveSuit(factory,110,82,170); factory=new ShanghaiClothesFactory(); shop.giveSuit(factory,120,88,180); 三、三、抽象工廠模式的優(yōu)點(diǎn)抽象工廠模式的優(yōu)點(diǎn) 抽象工廠模式可以為用戶創(chuàng)建一系列相關(guān)的對象,使得用戶和創(chuàng)建這些對象的類脫耦。使用抽象工廠模式可以方便的為用戶配置一系列對象。用戶使用不同的具體工廠就能得到一組相關(guān)的對象,同時(shí)也能避免用戶混用不同系列中的對象。在抽象工廠模式中,可以隨時(shí)增加“具體工廠”為用戶提供一組相關(guān)的對象。一一 、 一個(gè)實(shí)例一個(gè)實(shí)例 MINA框架中,數(shù)
36、據(jù)編碼處理的設(shè)計(jì)The Singleton Pattern Singleton模式應(yīng)用在系統(tǒng)中的某些對象有且只能有一個(gè)實(shí)例的情況下,也就是確保類只能實(shí)例化一次。很多類都是Singleton,例如Java語言里的System、Runtime和Math類,JDBC中的DriverManager等。Singleton模式的實(shí)現(xiàn) 利用Static Classes來實(shí)現(xiàn)。如Java語言中的System和Math類。 結(jié)合Factory模式實(shí)現(xiàn)。由于Factory負(fù)責(zé)對象的創(chuàng)建,在其中實(shí)現(xiàn)Singleton更優(yōu)雅且具彈性。此外,因多數(shù)Factory都要求只有一個(gè)實(shí)例,Abstract Factory的實(shí)現(xiàn)
37、廣泛采用了Singleton模式。模式的UML類圖 模式的結(jié)構(gòu)的描述與使用 1單件類(Singleton): Moon.java public class Moon private static Moon uniqueMoon; double radius; double distanceToEarth; private Moon() uniqueMoon=this; radius=1738; distanceToEarth=363300; public static synchronized Moon getMoon() if(uniqueMoon=null) uniqueMoon=new
38、Moon(); return uniqueMoon; public String show() String s=月亮的半徑是+radius+km,距地球是+distanceToEarth+km; return s; 模式的結(jié)構(gòu)的描述與使用 2應(yīng)用 Application.javaimport javax.swing.*;import java.awt.*;public class Application public static void main(String args) MyFrame f1=new MyFrame(張三看月亮); MyFrame f2=new MyFrame( 李四看
39、月亮); f1.setBounds(10,10,360,150); f2.setBounds(370,10,360,150); f1.validate(); f2.validate(); class MyFrame extends JFrame String str; MyFrame(String title) setTitle(title); Moon moon=Moon.getMoon(); str=moon.show(); setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); setVisible(true); repaint(); pub
40、lic void paint(Graphics g) super.paint(g); g.setFont(new Font(宋體,Font.BOLD,14); g.drawString(str,5,100); 單件模式的一些擴(kuò)展 枚舉 線程范圍內(nèi)單件原型原型模式模式 原型模式 用原型實(shí)例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象。Prototype Pattern Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this pr
41、ototype. 原型原型模式模式 java.lang.Object類的clone方法1.clone()方法:protected必須位于java.lang包中,用于復(fù)制對象。2.clone()方法的重寫:super.clone(),public;3.Cloneable接口:原型原型模式模式 class Circle implements Cloneableprivate double radius;public void setRadius(double r) radius=r;public double getRadius()return radius;public Object clone
42、() throws CloneNotSupportExceptionobject object=super.clone();return object;原型原型模式模式 Public class Examplepublic static void main(String args) Circle circle=new Circle();circle.setRadius(198.99);tryCircle circleCopy=(Circle)circle.clone();System.out.println(“circle對象中的數(shù)據(jù):”+circle.getRadius();System.o
43、ut.print l n ( “ c i r c l e C o py 對象中的數(shù)據(jù):”+circle.getRadius();)catch(CloneNotSupportedException exp)原型原型模式模式 Ox12310052898objectxyOx78910052898cloneobjectxyOx1230 x552898objectrectangleheightOx78910052898cloneobjectrectangleheight10052898mn一一 、 概述概述 原型模式是從一個(gè)對象出發(fā)得到一個(gè)和自己有相同狀態(tài)的新對象的成熟模式,該模式的關(guān)鍵是將一個(gè)對象定義
44、為原型,并為其提供復(fù)制自己的方法。 二、二、原型模式的結(jié)構(gòu)與使用原型模式的結(jié)構(gòu)與使用 模式的結(jié)構(gòu)中包括兩種角色:抽象原型(Prototype) 具體原型(Concrete Prototype) 模式的UML類圖 模式的結(jié)構(gòu)的描述與使用 1抽象原型(Prototype): Prototype.java public interface Prototype public Object cloneMe() throws CloneNotSupportedException,; 模式的結(jié)構(gòu)的描述與使用 2具體原型(Concrete Prototype)_1: Cubic.java public cla
45、ss Cubic implements Prototype, Cloneable double length,width,height; Cubic(double a,double b,double c) length=a; width=b; height=c; public Object cloneMe() throws CloneNotSupportedException Cubic object=(Cubic)clone(); return object; 模式的結(jié)構(gòu)的描述與使用 2具體原型(Concrete Prototype)_2: Goat.java import java.io.
46、*;public class Goat implements Prototype,Serializable StringBuffer color; public void setColor(StringBuffer c) color=c; public StringBuffer getColor() return color; public Object cloneMe() throws CloneNotSupportedException Object object=null; try ByteArrayOutputStream outOne=new ByteArrayOutputStrea
47、m(); ObjectOutputStream outTwo=new ObjectOutputStream(outOne); outTwo.writeObject(this); ByteArrayInputStream inOne= new ByteArrayInputStream(outOne.toByteArray(); ObjectInputStream inTwo=new ObjectInputStream(inOne); object=inTwo.readObject(); catch(Exception event) System.out.println(event); retur
48、n object; 模式的結(jié)構(gòu)的描述與使用 3應(yīng)用 Application.javapublic class Application public static void main(String args) Cubic cubic=new Cubic(12,20,66); System.out.println(cubic的長、寬和高:); System.out.println(cubic.length+,+cubic.width+,+cubic.height); try Cubic cubicCopy=(Cubic)cubic.cloneMe(); System.out.println(cub
49、icCopy的長、寬和高:); System.out.println(cubicCopy.length+,+cubicCopy.width+, +cubicCopy.height); catch(CloneNotSupportedException exp) Goat goat=new Goat(); goat.setColor(new StringBuffer(白顏色的山羊); System.out.println(goat是+goat.getColor(); try Goat goatCopy=(Goat)goat.cloneMe(); System.out.println(goatCop
50、y是+goatCopy.getColor(); System.out.println(goatCopy將自己的顏色改變成黑色); goatCopy.setColor(new StringBuffer(黑顏色的山羊); System.out.println(goat仍然是+goat.getColor(); System.out.println(goatCopy是+goatCopy.getColor(); catch(CloneNotSupportedException exp) 三、三、原型模式的優(yōu)點(diǎn)原型模式的優(yōu)點(diǎn) 當(dāng)創(chuàng)建類的新實(shí)例的代價(jià)更大時(shí),使用原型模式復(fù)制一個(gè)已有的實(shí)例可以提高創(chuàng)建新實(shí)例的
51、效率。可以動(dòng)態(tài)地保存當(dāng)前對象的狀態(tài)。在運(yùn)行時(shí)刻,可以隨時(shí)使用對象流保存當(dāng)前對象的一個(gè)復(fù)制品。生成器生成器模式模式 生成器模式將一個(gè)復(fù)雜對象的構(gòu)建與它的表示分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。Builder Pattern Separate the construction of a complex object from its representation so that the same construction process can create different representations. 一一 、 概述概述 當(dāng)系統(tǒng)準(zhǔn)備為用戶提供一個(gè)內(nèi)部結(jié)構(gòu)復(fù)雜的對象時(shí),就可以使用生
52、成器模式,使用該模式可以逐步地構(gòu)造對象,使得對象的創(chuàng)建更具彈性。生成器模式的關(guān)鍵是將一個(gè)包含有多個(gè)組件對象的創(chuàng)建分成若干個(gè)步驟,并將這些步驟封裝在一個(gè)稱作生成器的接口中。 一一 、 一個(gè)實(shí)例一個(gè)實(shí)例 創(chuàng)建含有按鈕、標(biāo)簽和文本框組件的容器。不同用戶對容器有不同的要求,比如某些用戶希望容器中只含有按鈕和標(biāo)簽,某些用戶希望容器只含有按鈕和文本框等。另外用戶對組件在容器中的順序位置也有不同的要求,比如某些用戶要求組件在容器中從左至右的排列順序是按鈕、標(biāo)簽、文本框,而某些用戶要求從左至右的排序時(shí)標(biāo)簽、文本框、按鈕。 二、二、生成器模式的結(jié)構(gòu)與使用生成器模式的結(jié)構(gòu)與使用 模式的結(jié)構(gòu)中包括四種角色:產(chǎn)品(P
53、roduct) 抽象生成器(Builder) 具體生成器(ConcreteBuilder) 指揮者(Director) 模式的UML類圖 模式的結(jié)構(gòu)的描述與使用 1產(chǎn)品(Product): PanelProduct.java import javax.swing.*;public class PanelProduct extends JPanel JButton button; JLabel label; JTextField textField;模式的結(jié)構(gòu)的描述與使用 2抽象生成器(Builder): Builer.java import.javax.swing.*;public inter
54、face Builder public abstract void buildButton(); public abstract void buildLabel(); public abstract void buildTextField(); public abstract JPanel getPanel();模式的結(jié)構(gòu)的描述與使用 3具體生成器(ConcreteBuilder)_1:ConcreteBuilderOne.java import javax.swing.*;public class ConcreteBuilderOne implements Builder private P
55、anelProduct panel; ConcreteBuilderOne() panel=new PanelProduct(); public void buildButton() panel.button=new JButton(按鈕); public void buildLabel() panel.label=new JLabel(標(biāo)簽); public void buildTextField() public JPanel getPanel() panel.add(panel.button); panel.add(panel.label); return panel; 模式的結(jié)構(gòu)的描述
56、與使用 3具體生成器(ConcreteBuilder)_2:ConcreteBuilderTwo.java import javax.swing.*;public class ConcreteBuilderTwo implements Builder private PanelProduct panel; ConcreteBuilderTwo() panel=new PanelProduct(); public void buildButton() panel.button=new JButton(button); public void buildLabel() public void bu
57、ildTextField() panel.textField=new JTextField(textField); public JPanel getPanel() panel.add(panel.textField); panel.add(panel.button); return panel; 模式的結(jié)構(gòu)的描述與使用 4指揮者(Director):Director.java import javax.swing.*;public class Director private Builder builder; Director(Builder builder) this.builder=bu
58、ilder; public JPanel constructProduct() builder.buildButton(); builder.buildLabel(); builder.buildTextField(); JPanel product=builder.getPanel(); return product; 模式的結(jié)構(gòu)的描述與使用 5應(yīng)用 Application.javaimport javax.swing.*;public class Application public static void main(String args) Builder builder=new Con
59、creteBuilderOne(); Director director=new Director(builder); JPanel panel=director.constructProduct(); JFrame frameOne=new JFrame(); frameOne.add(panel); frameOne.setBounds(12,12,200,120); frameOne.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frameOne.setVisible(true); builder=new ConcreteBuild
60、erTwo(); director=new Director(builder); panel=director.constructProduct(); JFrame frameTwo=new JFrame(); frameTwo.add(panel); frameTwo.setBounds(212,12,200,120); frameTwo.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); frameTwo.setVisible(true); 三、三、生成器模式的優(yōu)點(diǎn)生成器模式的優(yōu)點(diǎn) 生成器模式將對象的構(gòu)造過程封裝在具體生成器中,用戶使用不同
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年農(nóng)作物種子繁育員資格考試題型總結(jié)試題及答案
- 2024年游泳救生員考試的課題試題及答案
- 2024年農(nóng)作物種子檢驗(yàn)流程試題及答案
- 聚焦亮點(diǎn) 2024年體育經(jīng)紀(jì)人試題及答案
- 2025年中國保齡球球道油市場調(diào)查研究報(bào)告
- 農(nóng)作物種子繁育員備考的行業(yè)動(dòng)態(tài)輔導(dǎo)試題及答案
- 2024籃球裁判員考試?yán)碚撝R(shí)試題及答案
- 2024年無人機(jī)執(zhí)照考核的評審標(biāo)準(zhǔn)試題及答案
- 無人機(jī)專用軟件使用知識(shí)試題及答案
- 游泳救生員考試技巧性總結(jié)與試題答案
- 2024年東南亞紙巾商銷(AFH)市場深度研究及預(yù)測報(bào)告
- 服務(wù)質(zhì)量保障措施及進(jìn)度保障措施
- 七層垂直循環(huán)式立體車庫
- 中國子宮內(nèi)膜增生管理指南(2022)解讀
- 電力設(shè)備保修承諾書范本
- 患者發(fā)生譫妄的應(yīng)急預(yù)案與流程
- 酸棗仁湯的劑型研究
- 甘肅省蘭州市2022-2023學(xué)年七年級(jí)下學(xué)期數(shù)學(xué)期中考試試卷(含答案)
- 教育機(jī)構(gòu)課程顧問標(biāo)準(zhǔn)銷售流程
- 俄羅斯阿爾泰山脈的生態(tài)保護(hù)與旅游業(yè)
- (2024年)夾具設(shè)計(jì)培訓(xùn)
評論
0/150
提交評論