設(shè)計(jì)模式與用戶界面設(shè)計(jì).ppt
軟件工程導(dǎo)論,劉春計(jì)算機(jī)與信息工程學(xué)院軟件工程系,兩種軟件開發(fā)方法,結(jié)構(gòu)化方法,面向?qū)ο蠓椒?3,回顧,面向?qū)ο笤O(shè)計(jì)方法概述系統(tǒng)設(shè)計(jì)軟件體系結(jié)構(gòu)設(shè)計(jì)硬件體系結(jié)構(gòu)設(shè)計(jì)詳細(xì)設(shè)計(jì)對象設(shè)計(jì)對象持久化設(shè)計(jì)面向?qū)ο蟮脑O(shè)計(jì)原則設(shè)計(jì)模式,將信息系統(tǒng)中比較關(guān)心的對象分層,可分為三層:用戶界面層、業(yè)務(wù)層、數(shù)據(jù)訪問層,再把各層中的一些公共部分提出來:權(quán)限管理、異常處理,這樣得到包圖如下:,軟件體系結(jié)構(gòu)的設(shè)計(jì):以信息系統(tǒng)為例,用戶界面層的職責(zé)是:與用戶的交互,接收用戶的各種輸入以及輸出各種提示信息或處理結(jié)果。對于輸入的數(shù)據(jù)進(jìn)行數(shù)據(jù)校驗(yàn),過濾非法數(shù)據(jù)。向業(yè)務(wù)處理對象發(fā)送處理請求。,1、用戶界面層,2、業(yè)務(wù)處理包,業(yè)務(wù)處理層的職責(zé)是:實(shí)現(xiàn)各種業(yè)務(wù)處理邏輯或處理算法。驗(yàn)證請求者的權(quán)限。向數(shù)據(jù)訪問對象發(fā)送數(shù)據(jù)持久化操作的請求。向用戶界面層返回處理結(jié)果。,3、數(shù)據(jù)訪問包,數(shù)據(jù)訪問層的職責(zé)是:實(shí)現(xiàn)數(shù)據(jù)的持久化操作實(shí)現(xiàn)事務(wù)處理,權(quán)限管理的主要職責(zé)是:驗(yàn)證請求者的請求權(quán)限提供請求者的權(quán)限列表,注:業(yè)務(wù)處理對象通過權(quán)限管理對象來驗(yàn)證權(quán)限,4、權(quán)限管理包,5、異常處理包,異常處理的職責(zé):匯報(bào)運(yùn)行時(shí)的詳細(xì)異常信息記錄異常處理日志,6、信息系統(tǒng)的體系結(jié)構(gòu)的類圖,硬件系統(tǒng)體系結(jié)構(gòu)模型顯示硬件的結(jié)構(gòu),包括不同的節(jié)點(diǎn)和這些節(jié)點(diǎn)之間如何連接,硬件體系結(jié)構(gòu)設(shè)計(jì),12,內(nèi)容提綱,面向?qū)ο笤O(shè)計(jì)方法概述系統(tǒng)設(shè)計(jì)軟件體系結(jié)構(gòu)設(shè)計(jì)硬件體系結(jié)構(gòu)設(shè)計(jì)詳細(xì)設(shè)計(jì)對象設(shè)計(jì)對象持久化設(shè)計(jì)面向?qū)ο蟮脑O(shè)計(jì)原則設(shè)計(jì)模式,主要包括對象設(shè)計(jì)和對象持久化設(shè)計(jì)(數(shù)據(jù)庫設(shè)計(jì))對象設(shè)計(jì):對象接口設(shè)計(jì):確定對象的主要職責(zé)(對象倒底應(yīng)該做什么)屬性和操作的設(shè)計(jì):設(shè)計(jì)屬性的數(shù)據(jù)結(jié)構(gòu)、類型,以及操作的算法、參數(shù)類型、返回值等對象持久化設(shè)計(jì):數(shù)據(jù)對象的存儲和檢索,詳細(xì)設(shè)計(jì),永久類的存儲設(shè)計(jì)永久類一般都是實(shí)體類,對應(yīng)的是系統(tǒng)中涉及的數(shù)據(jù)每一個(gè)永久類映射為一個(gè)關(guān)系表,表格的列或字段對應(yīng)類的屬性,而行或記錄對應(yīng)類的實(shí)例(對象)關(guān)聯(lián)的存儲設(shè)計(jì)1:1關(guān)聯(lián):在一個(gè)類對應(yīng)的表中用外鍵隱含管理1:n關(guān)聯(lián):在n端類對應(yīng)的表中用外鍵隱含關(guān)聯(lián)n:n關(guān)聯(lián):轉(zhuǎn)換成1:n管理,然后按照上面的方法進(jìn)行轉(zhuǎn)換,基于關(guān)系數(shù)據(jù)庫的對象持久化設(shè)計(jì),1:1關(guān)聯(lián),1:n關(guān)聯(lián),17,內(nèi)容提綱,面向?qū)ο笤O(shè)計(jì)方法概述系統(tǒng)設(shè)計(jì)軟件體系結(jié)構(gòu)設(shè)計(jì)硬件體系結(jié)構(gòu)設(shè)計(jì)詳細(xì)設(shè)計(jì)對象設(shè)計(jì)對象持久化設(shè)計(jì)面向?qū)ο蟮脑O(shè)計(jì)原則設(shè)計(jì)模式,單一職責(zé)原則開放-封閉原則接口隔離原則Liskov替換原則依賴倒置原則,面向?qū)ο笤O(shè)計(jì)原則,一個(gè)類只完成某一類功能(職責(zé))盡可能避免出現(xiàn)一個(gè)“復(fù)合”功能的類在同一個(gè)類中完成多個(gè)不同的功能,1、單一職責(zé)原則,開放封閉原則:軟件實(shí)體類(類、模塊、函數(shù)等)應(yīng)該是可以擴(kuò)展、但是不可修改的基本思想:不用修改原有類就能擴(kuò)展一個(gè)類的行為,2、開放封閉原則,什么是不封閉、不開放,如下的模型可以處理月薪制和時(shí)薪制職工工資,如果還要增加一種職工類型,其計(jì)酬方式不同(如提成制),則必定要修改Employee類,如何改進(jìn),利用抽象機(jī)制封閉:Employee及其子類是封閉的開放:可以派生新的子類,實(shí)現(xiàn)新的需求,Liskov替換原則:子類應(yīng)當(dāng)可以替換父類并出現(xiàn)在父類能夠出現(xiàn)的任何地方核心思想:子類型必須能夠替換它們的基類型,該原則能夠知道設(shè)計(jì)人員正確地進(jìn)行類的繼承與派生,3、Liskov替換原則,一個(gè)違反Liskov原則的例子,正方形是長方形的一種特例,正方形有獨(dú)特的行為方式通過覆蓋父類的有關(guān)方法來實(shí)現(xiàn)子類行為,實(shí)際中的使用情況,長方形的使用者按照長方形的特點(diǎn)來調(diào)用SetWidth和SetHeight兩個(gè)函數(shù),并測試面積,代碼如下:voidtestArea(Rectangle如果傳遞進(jìn)來的是Square對象又會如何呢?顯然會出現(xiàn)斷言錯(cuò)誤,測試失敗。對于客戶程序來說,模型中的層次結(jié)構(gòu)是脆弱的,因?yàn)檫`反了LSP替換原則,Square對象和Rectangle對象的行為方式不相容,4、接口隔離原則,接口隔離原則:采用多個(gè)與特定客戶類有關(guān)的接口比采用一個(gè)通用的涵蓋多個(gè)業(yè)務(wù)方法的接口更好。對接口的污染設(shè)計(jì)人員為了節(jié)省接口數(shù)目,而經(jīng)常將一些功能相近或功能相關(guān)的接口合并成一個(gè)總的接口臃腫的大接口,面向過程自頂向下,逐步求精,形成上對下依賴依賴倒置原則:應(yīng)用系統(tǒng)中的高層模塊不應(yīng)依賴于底層模塊;抽象不應(yīng)該依賴于細(xì)節(jié)實(shí)現(xiàn),實(shí)現(xiàn)細(xì)節(jié)應(yīng)該依賴于抽象。優(yōu)點(diǎn):復(fù)用、靈活性、易維護(hù),5、依賴倒置原則,32,內(nèi)容提綱,面向?qū)ο笤O(shè)計(jì)方法概述系統(tǒng)設(shè)計(jì)軟件體系結(jié)構(gòu)設(shè)計(jì)硬件體系結(jié)構(gòu)設(shè)計(jì)詳細(xì)設(shè)計(jì)對象設(shè)計(jì)對象持久化設(shè)計(jì)面向?qū)ο蟮脑O(shè)計(jì)原則設(shè)計(jì)模式,33,第十一章設(shè)計(jì)模式與用戶界面設(shè)計(jì),34,內(nèi)容提綱,設(shè)計(jì)模式概述經(jīng)典設(shè)計(jì)模式介紹用戶界面設(shè)計(jì),什么是設(shè)計(jì)模式?,設(shè)計(jì)模式:描述一個(gè)在我們周圍不斷重復(fù)發(fā)生的問題,以及該問題的解決方案。,使用設(shè)計(jì)模式,我們就能一次一次地利用已有方案而不必做重復(fù)勞動。,設(shè)計(jì)模式的起源,軟件設(shè)計(jì)模式起源于建筑學(xué)1977年,建筑大師Alexander出版了APatternLanguage:Towns,Building,Construction一書受Alexander的影響,KentBeck和WardCunningham在1987年舉行的一次面向?qū)ο蟮臅h上發(fā)表了論文:在面向?qū)ο缶幊讨惺褂媚J?設(shè)計(jì)模式的四個(gè)基本要素,模式名稱一個(gè)助記名,用幾個(gè)詞來描述模式的問題、解決方案和效果。問題描述了應(yīng)該在何時(shí)使用模式。它解釋了設(shè)計(jì)問題和問題存在的前因后果。有時(shí)候,問題部分會包括使用模式必須滿足的一系列先決條件。解決方案描述了設(shè)計(jì)的組成成分,它們之間的相互關(guān)系及各自的職責(zé)和協(xié)作方式。因?yàn)槟J骄拖褚粋€(gè)模板,可應(yīng)用于多種不同場合,所以解決方案并不描述一個(gè)特定而具體的設(shè)計(jì)或?qū)崿F(xiàn),而是提供設(shè)計(jì)問題的抽象描述和怎樣用一個(gè)具有一般意義的元素組合(類或?qū)ο蠼M合)來解決這個(gè)問題。效果描述了模式應(yīng)用的效果及使用模式應(yīng)權(quán)衡的問題。比如模式的使用對系統(tǒng)的靈活性、擴(kuò)充性或可移植性的影響。,為什么學(xué)習(xí)設(shè)計(jì)模式?,學(xué)習(xí)設(shè)計(jì)模式不僅可以使我們使用好這些成功的模式,利用已有的設(shè)計(jì)經(jīng)驗(yàn)更重要的是可以使我們更加深刻地理解面向?qū)ο蟮脑O(shè)計(jì)思想,非常有利于我們更好地使用面向?qū)ο笳Z言解決設(shè)計(jì)中的問題。,設(shè)計(jì)模式之四人幫(GOF),GOF:GangofFourErichGamma、RichardHelm、RalphJohnson、JohnVlissides),GOF之書,GOF之書:DesignPatterns:ElementsofReusableObject-OrientedSoftware(設(shè)計(jì)模式:可復(fù)用的面向?qū)ο筌浖幕驹恚?。該書被廣大喜愛者昵稱為GOF之書,被認(rèn)為是學(xué)習(xí)設(shè)計(jì)模式的必讀著作,GOF之書已經(jīng)被公認(rèn)為是設(shè)計(jì)模式領(lǐng)域的奠基之作。,GOF之23種設(shè)計(jì)模式,創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式結(jié)構(gòu)型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,行為型模式1.迭代器模式2.觀察者模式3.策略模式4.職責(zé)鏈模式5.命令模式6.解釋器模式7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,創(chuàng)建型模式關(guān)注的是如何創(chuàng)建對象而不是直接實(shí)例化對象,這會使程序在判斷給定情況下創(chuàng)建哪一個(gè)對象時(shí)更為靈活五種創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式,創(chuàng)建型模式,結(jié)構(gòu)型模式關(guān)注的是如何將一組對象組合成更大的結(jié)構(gòu)七種創(chuàng)建型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,結(jié)構(gòu)型模式,行為型模式關(guān)注的是如何定義系統(tǒng)內(nèi)對像間的通信,以及復(fù)雜程序中的流程控制十一種創(chuàng)建型模式1.迭代器模式2.觀察者模式3.策略模式4.職責(zé)鏈模式5.命令模式6.解釋器模式,行為型模式,7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,45,內(nèi)容提綱,設(shè)計(jì)模式概述經(jīng)典設(shè)計(jì)模式介紹用戶界面設(shè)計(jì),經(jīng)典設(shè)計(jì)模式介紹,創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式結(jié)構(gòu)型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,行為型模式1.迭代器模式2.觀察者模式3.策略模式4.命令模式5.職責(zé)鏈模式6.解釋器模式7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,參考:清華大學(xué)耿祥義JAVA設(shè)計(jì)模式的課件,經(jīng)典設(shè)計(jì)模式:抽象工廠模式,抽象工廠模式:提供一個(gè)創(chuàng)建一系列(相互依賴)對象的接口,而無需指定它們具體的類。應(yīng)用背景:當(dāng)系統(tǒng)準(zhǔn)備為用戶提供一系列相關(guān)的對象,又不想讓用戶代碼和創(chuàng)建這些對象的類形成耦合時(shí),就可以使用抽象工廠方法模式來設(shè)計(jì)系統(tǒng)。抽象工廠模式的關(guān)鍵:是在一個(gè)抽象類或接口中定義若干個(gè)抽象方法,這些抽象方法分別返回某個(gè)類的實(shí)例,該抽象類或接口讓其子類或?qū)崿F(xiàn)該接口的類重寫這些抽象方法,為用戶提供一系列相關(guān)的對象。,抽象工廠模式的結(jié)構(gòu),模式的結(jié)構(gòu)中包括四種角色:抽象產(chǎn)品(Prodcut)具體產(chǎn)品(ConcreteProduct)抽象工廠(AbstractFactory)具體工廠(ConcreteFactory),抽象工廠模式的UML圖,抽象工廠模式的應(yīng)用實(shí)例,建立一個(gè)系統(tǒng),該系統(tǒng)可以為用戶提供西服套裝(上衣褲子)和牛仔套裝(上衣褲子)。,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),1抽象產(chǎn)品(Product):UpperClothes.javapublicabstractclassUpperClothespublicabstractintgetChestSize();publicabstractintgetHeight();publicabstractStringgetName();Trousers.javapublicabstractclassTrouserspublicabstractintgetWaistSize();publicabstractintgetHeight();publicabstractStringgetName();,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),2具體產(chǎn)品(ConcreteProduct)_1:WesternUpperClothes.javapublicclassWesternUpperClothesextendsUpperClothesprivateintchestSize;privateintheight;privateStringname;WesternUpperClothes(Stringname,intchestSize,intheight)this.name=name;this.chestSize=chestSize;this.height=height;publicintgetChestSize()returnchestSize;publicintgetHeight()returnheight;publicStringgetName()returnname;,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),2具體產(chǎn)品(ConcreteProduct)_2:CowboyUpperClothes.javapublicclassCowboyUpperClothesextendsUpperClothesprivateintchestSize;privateintheight;privateStringname;CowboyUpperClothes(Stringname,intchestSize,intheight)this.name=name;this.chestSize=chestSize;this.height=height;publicintgetChestSize()returnchestSize;publicintgetHeight()returnheight;publicStringgetName()returnname;,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),2具體產(chǎn)品(ConcreteProduct)_3:WesternTrousers.javapublicclassWesternTrousersextendsTrousersprivateintwaistSize;privateintheight;privateStringname;WesternTrousers(Stringname,intwaistSize,intheight)this.name=name;this.waistSize=waistSize;this.height=height;publicintgetWaistSize()returnwaistSize;publicintgetHeight()returnheight;publicStringgetName()returnname;,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),2具體產(chǎn)品(ConcreteProduct)_4:CowboyTrousers.javapublicclassCowboyTrousersextendsTrousersprivateintwaistSize;privateintheight;privateStringname;CowboyTrousers(Stringname,intwaistSize,intheight)this.name=name;this.waistSize=waistSize;this.height=height;publicintgetWaistSize()returnwaistSize;publicintgetHeight()returnheight;publicStringgetName()returnname;,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),3抽象工廠(AbstractFactory):ClothesFactory.javapublicabstractclassClothesFactorypublicabstractUpperClothescreateUpperClothes(intchestSize,intheight);publicabstractTrouserscreateTrousers(intwaistSize,intheight);,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),4具體工廠(ConcreteFactory):BeijingClothesFactory.javapublicclassBeijingClothesFactoryextendsClothesFactorypublicUpperClothescreateUpperClothes(intchestSize,intheight)returnnewWesternUpperClothes("北京牌西服上衣",chestSize,height);publicTrouserscreateTrousers(intwaistSize,intheight)returnnewWesternTrousers("北京牌西服褲子",waistSize,height);ShanghaiClothesFactory.javapublicclassShanghaiClothesFactoryextendsClothesFactorypublicUpperClothescreateUpperClothes(intchestSize,intheight)returnnewWesternUpperClothes("上海牌牛仔上衣",chestSize,height);publicTrouserscreateTrousers(intwaistSize,intheight)returnnewWesternTrousers("上海牌牛仔褲",waistSize,height);,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),5應(yīng)用_1:Shop.javapublicclassShopUpperClothescloth;Trouserstrouser;publicvoidgiveSuit(ClothesFactoryfactory,intchestSize,intwaistSize,intheight)cloth=factory.createUpperClothes(chestSize,height);trouser=factory.createTrousers(waistSize,height);showMess();privatevoidshowMess()System.out.println("");System.out.println(cloth.getName()+":");System.out.print("胸圍:"+cloth.getChestSize();System.out.println("身高:"+cloth.getHeight();System.out.println(trouser.getName()+":");System.out.print("腰圍:"+trouser.getWaistSize();System.out.println("身高:"+trouser.getHeight();,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),5應(yīng)用_2:Application.javapublicclassApplicationpublicstaticvoidmain(Stringargs)Shopshop=newShop();ClothesFactoryfactory=newBeijingClothesFactory();shop.giveSuit(factory,110,82,170);factory=newShanghaiClothesFactory();shop.giveSuit(factory,120,88,180);,抽象工廠的優(yōu)點(diǎn),抽象工廠模式可以為用戶創(chuàng)建一系列相關(guān)的對象,使得用戶和創(chuàng)建這些對象的類脫耦。在抽象工廠模式中,可以隨時(shí)增加“具體工廠”為用戶提供一組相關(guān)的對象。,經(jīng)典設(shè)計(jì)模式介紹,創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式結(jié)構(gòu)型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,行為型模式1.迭代器模式2.觀察者模式3.策略模式4.命令模式5.職責(zé)鏈模式6.解釋器模式7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,經(jīng)典設(shè)計(jì)模式:工廠方法模式,工廠方法模式:定義一個(gè)用于創(chuàng)建對象的接口,讓子類決定實(shí)例化哪一個(gè)類。工廠方法使一個(gè)類的實(shí)例化延遲到其子類應(yīng)用背景:當(dāng)系統(tǒng)準(zhǔn)備為用戶提供某個(gè)類的子類的實(shí)例,又不想讓用戶代碼和該子類形成耦合時(shí),就可以使用工廠方法模式來設(shè)計(jì)系統(tǒng)抽象工廠模式的關(guān)鍵:是在一個(gè)接口或抽象類中定義一個(gè)抽象方法,該方法返回某個(gè)類的子類的實(shí)例,該抽象類或接口讓其子類或?qū)崿F(xiàn)該接口的類通過重寫這個(gè)抽象方法返回某個(gè)子類的實(shí)例,工廠方法模式的結(jié)構(gòu),模式的結(jié)構(gòu)中包括四種角色:抽象產(chǎn)品(Prodcut)具體產(chǎn)品(ConcreteProduct)構(gòu)造者(Creator)具體構(gòu)造者(ConcreteCreator),工廠方法模式的UML圖,工廠方法模式的應(yīng)用實(shí)例,假設(shè)有三個(gè)筆芯,分別是紅筆芯、藍(lán)筆芯和黑筆芯。用戶希望通過圓珠筆來明確筆芯的顏色。,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(1/3),1抽象產(chǎn)品(Product):PenCore.javapublicabstractclassPenCoreStringcolor;publicabstractvoidwriteWord(Strings);,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(2/3),2具體產(chǎn)品(ConcreteProduct)_1:RedPenCore.javapublicclassRedPenCoreextendsPenCoreRedPenCore()color="紅色"publicvoidwriteWord(Strings)System.out.println("寫出"+color+"的字:"+s);,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(3/3),2具體產(chǎn)品(ConcreteProduct)_2:BluePenCore.javapublicclassBluePenCoreextendsPenCoreBluePenCore()color="藍(lán)色"publicvoidwriteWord(Strings)System.out.println("寫出"+color+"的字:"+s);,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(4/3),2具體產(chǎn)品(ConcreteProduct)_3:BlackPenCore.javapublicclassBlackPenCoreextendsPenCoreBlackPenCore()color="黑色"publicvoidwriteWord(Strings)System.out.println("寫出"+color+"的字:"+s);,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(5/3),3構(gòu)造者(Creator):BallPen.javapublicabstractclassBallPenBallPen()System.out.println("生產(chǎn)了一只裝有"+getPenCore().color+"筆芯的圓珠筆");publicabstractPenCoregetPenCore();/工廠方法,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(6/3),4具體構(gòu)造者(ConcreteCreator):RedBallPen.javapublicclassRedBallPenextendsBallPenpublicPenCoregetPenCore()returnnewRedPenCore();BlueBallPen.javapublicclassBlueBallPenextendsBallPenpublicPenCoregetPenCore()returnnewBluePenCore();BlackBallPen.javapublicclassBlackBallPenextendsBallPenpublicPenCoregetPenCore()returnnewBlackPenCore();,模式結(jié)構(gòu)中每個(gè)部分的描述與使用(7/3),5應(yīng)用Application.javapublicclassApplicationpublicstaticvoidmain(Stringargs)PenCorepenCore;BallPenballPen=newBlueBallPen();penCore=ballPen.getPenCore();penCore.writeWord("你好,很高興認(rèn)識你");ballPen=newRedBallPen();penCore=ballPen.getPenCore();penCore.writeWord("Howareyou");ballPen=newBlackBallPen();penCore=ballPen.getPenCore();penCore.writeWord("nicetomeetyou");,工廠方法的優(yōu)點(diǎn),使用工廠方法可以讓用戶的代碼和某個(gè)特定類的子類的代碼解耦。工廠方法使用戶不必知道它所使用的對象是怎樣被創(chuàng)建的,只需知道該對象有哪些方法即可,經(jīng)典設(shè)計(jì)模式介紹,創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式結(jié)構(gòu)型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,行為型模式1.迭代器模式2.觀察者模式3.策略模式4.命令模式5.職責(zé)鏈模式6.解釋器模式7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,經(jīng)典設(shè)計(jì)模式:單例模式,單例模式:保證一個(gè)類僅有一個(gè)實(shí)例(對象),并提供一個(gè)訪問它的全局訪問點(diǎn)應(yīng)用背景:怎樣設(shè)計(jì)一個(gè)類,并使得該類只有一個(gè)實(shí)例(也即對象)單例模式的關(guān)鍵:是將類的構(gòu)造方法設(shè)置為private,并提供一個(gè)返回它的唯一實(shí)例的類方法。,單例模式的結(jié)構(gòu),模式的結(jié)構(gòu)中包括一種角色:單例類(Singleton),單例模式的應(yīng)用實(shí)例(1/2),1單例類(Singleton):Moon.javapublicclassMoonprivatestaticMoonuniqueMoon;doubleradius;doubledistanceToEarth;privateMoon()uniqueMoon=this;radius=1738;distanceToEarth=363300;publicstaticMoongetMoon()if(uniqueMoon=null)uniqueMoon=newMoon();returnuniqueMoon;publicStringshow()Strings="月亮的半徑是"+radius+"km,距地球是"+distanceToEarth+"km"returns;,單例模式的應(yīng)用實(shí)例(1/2),2應(yīng)用Application.javaimportjavax.swing.*;importjava.awt.*;publicclassApplicationpublicstaticvoidmain(Stringargs)MyFramef1=newMyFrame("張三看月亮");MyFramef2=newMyFrame("李四看月亮");f1.setBounds(10,10,360,150);f2.setBounds(370,10,360,150);f1.validate();f2.validate();classMyFrameextendsJFrameStringstr;MyFrame(Stringtitle)setTitle(title);Moonmoon=Moon.getMoon();str=moon.show();setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);setVisible(true);repaint();publicvoidpaint(Graphicsg)super.paint(g);g.setFont(newFont("宋體",Font.BOLD,14);g.drawString(str,5,100);,單例模式的優(yōu)點(diǎn),單例類的唯一實(shí)例由單例類本身來控制,所以可以很好地控制用戶何時(shí)訪問它,經(jīng)典設(shè)計(jì)模式介紹,創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式結(jié)構(gòu)型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,行為型模式1.迭代器模式2.觀察者模式3.策略模式4.命令模式5.職責(zé)鏈模式6.解釋器模式7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,經(jīng)典設(shè)計(jì)模式:適配器模式,適配器模式:將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。適配器模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。應(yīng)用背景:如何在不修改代碼的情況下,將一個(gè)接口修改為另外一個(gè)接口適配器模式的關(guān)鍵:是建立一個(gè)適配器,這個(gè)適配器實(shí)現(xiàn)了目標(biāo)接口并包含有被適配者的引用。,適配器模式的結(jié)構(gòu),模式的結(jié)構(gòu)中包括三種角色:目標(biāo)(Target)被適配者(Adaptee)適配器(Adapter),適配器模式的UML圖,適配器模式的優(yōu)點(diǎn),目標(biāo)(Target)和被適配者(Adaptee)是完全解耦的關(guān)系。適配器模式滿足“開-閉原則”。當(dāng)添加一個(gè)實(shí)現(xiàn)Adaptee接口的新類時(shí),不必修改Adapter,Adapter就能對這個(gè)新類的實(shí)例進(jìn)行適配。,經(jīng)典設(shè)計(jì)模式介紹,創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式結(jié)構(gòu)型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,行為型模式1.迭代器模式2.觀察者模式3.策略模式4.命令模式5.職責(zé)鏈模式6.解釋器模式7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,經(jīng)典設(shè)計(jì)模式:外觀模式,外觀模式:為系統(tǒng)中的一組接口提供一個(gè)一致的界面,外觀模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。應(yīng)用背景:簡化用戶和子系統(tǒng)(包含多個(gè)類)的交互外觀模式的關(guān)鍵:是為各個(gè)子系統(tǒng)提供一個(gè)稱作外觀的類,該外觀類的實(shí)例負(fù)責(zé)和各個(gè)子系統(tǒng)中類的實(shí)例打交道,外觀模式的結(jié)構(gòu),模式的結(jié)構(gòu)中包括兩種角色:子系統(tǒng)(Subsystem)外觀(Facade),外觀模式的UML圖,外觀模式的應(yīng)用實(shí)例(1/5),報(bào)社的廣告系統(tǒng)有三個(gè)類CheckWord、Charge和TypeSetting類,各個(gè)類的職責(zé)如下:CheckWord類負(fù)責(zé)檢查廣告內(nèi)容含有的字符數(shù)量;Charge類的實(shí)例負(fù)責(zé)計(jì)算費(fèi)用;TypeSetting的實(shí)例負(fù)責(zé)對廣告進(jìn)行排版,外觀模式的應(yīng)用實(shí)例(2/5),1子系統(tǒng)(Subsystem)_1:CheckWord.javapublicclassCheckWordpublicfinalintbasicAmount=85;Stringadvertisement;intamount;publicCheckWord(Stringadvertisement)this.advertisement=advertisement;publicvoidsetChargeAmount()amount=advertisement.length()+basicAmount;/計(jì)算出計(jì)費(fèi)字符數(shù)目publicintgetAmount()returnamount;,外觀模式的應(yīng)用實(shí)例(3/5),1子系統(tǒng)(Subsystem)_2:Charge.javapublicclassChargepublicfinalintbasicCharge=12;CheckWordcheckWord;Charge(CheckWordcheckWord)this.checkWord=checkWord;publicvoidgiveCharge()intcharge=checkWord.getAmount()*basicCharge;System.out.println("廣告費(fèi)用:"+charge+"元");,外觀模式的應(yīng)用實(shí)例(4/5),1子系統(tǒng)(Subsystem)_3:TypeSeting.javapublicclassTypeSetingStringadvertisement;publicTypeSeting(Stringadvertisement)this.advertisement=advertisement;publicvoidtypeSeting()System.out.println("廣告排版格式:");System.out.println("*");System.out.println(advertisement);System.out.println("*");,外觀模式的應(yīng)用實(shí)例(5/5),2外觀(Facade):ClientServerFacade.javapublicclassClientServerFacadeprivateCheckWordcheckWord;privateChargecharge;privateTypeSetingtypeSeting;Stringadvertisement;publicClientServerFacade(Stringadvertisement)this.advertisement=advertisement;checkWord=newCheckWord(advertisement);charge=newCharge(checkWord);typeSeting=newTypeSeting(advertisement);publicvoiddoAdvertisement()checkWord.setChargeAmount();charge.giveCharge();typeSeting.typeSeting();,外觀模式的應(yīng)用實(shí)例(6/5),3應(yīng)用Application.javapublicclassApplicationpublicstaticvoidmain(Stringargs)ClientServerFacadeclientFacade;StringclientAdvertisement="鹿花牌洗衣機(jī),價(jià)格2356元,聯(lián)系電話:1234567"clientFacade=newClientServerFacade(clientAdvertisement);clientFacade.doAdvertisement();,外觀模式的優(yōu)點(diǎn),使客戶和子系統(tǒng)中的類無耦合。外觀只是提供了一個(gè)更加簡潔的界面,并不影響用戶直接使用子系統(tǒng)中的類。子系統(tǒng)中任何類對其方法的內(nèi)容進(jìn)行修改,不影響外觀的代碼。,經(jīng)典設(shè)計(jì)模式介紹,創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式結(jié)構(gòu)型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,行為型模式1.迭代器模式2.觀察者模式3.策略模式4.命令模式5.職責(zé)鏈模式6.解釋器模式7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,經(jīng)典設(shè)計(jì)模式:迭代器模式,迭代器模式:提供一種方法順序訪問一個(gè)聚合對象中的各個(gè)元素,而又不需要暴露該對象的內(nèi)部表示應(yīng)用背景:如何高效的遍歷一個(gè)集合中的每一個(gè)元素迭代器模式的關(guān)鍵:是將遍歷集合的任務(wù)交給一個(gè)稱作迭代器的對象,迭代器模式的結(jié)構(gòu),模式的結(jié)構(gòu)中包括四種角色:集合(Aggregate)具體集合(ConcreteAggregate)迭代器(Iterator)具體迭代器(ConcreteIterator),迭代器模式的UML圖,迭代器模式的應(yīng)用實(shí)例(1/5),1集合(Aggregate):在這里我們使用java.util包中的Collection接口作為模式中的集合角色。Java所有的集合都實(shí)現(xiàn)了該接口。,2具體集合(ConcreteAggregate):在這里我們使用java.util包中的HashSet類的實(shí)例作為模式中的具體集合角色。,迭代器模式的應(yīng)用實(shí)例(2/5),3迭代器(Iterator):在本問題中,我們使用的迭代器是java.util包中的Itertator接口。,4具體迭代器(ConcreteIterator)HashSet創(chuàng)建的集合可以使用iterator()方法返回一個(gè)實(shí)現(xiàn)Iterator接口類的實(shí)例,即一個(gè)具體迭代器。,迭代器模式的應(yīng)用實(shí)例(3/5),5應(yīng)用Application.java_1importjava.util.*;publicclassApplicationpublicstaticvoidmain(Stringargs)intn=20;intsum=0;Collectionset=newHashSet();for(inti=1;iiterator=set.iterator();intjia=1,zhen=1;System.out.println("保險(xiǎn)箱共有"+set.size()+"張人民幣");intk=0;while(iterator.hasNext()RenMinMonymoney=iterator.next();k+;if(money.getIsTrue()=false)System.out.println("第"+k+"張是假幣,被銷毀");iterator.remove();k+;System.out.println("保險(xiǎn)箱現(xiàn)有真人民幣"+set.size()+"張,總價(jià)值是:");iterator=set.iterator();while(iterator.hasNext()RenMinMonymoney=iterator.next();sum=sum+money.getValue();System.out.println(sum+"元");,迭代器模式的應(yīng)用實(shí)例(4/5),5應(yīng)用Application.java_2classRenMinMonyintvalue;privatebooleanisTrue;RenMinMony(intvalue,booleanb)this.value=value;isTrue=b;publicbooleangetIsTrue()returnisTrue;publicintgetValue()returnvalue;,迭代器模式的優(yōu)點(diǎn),用戶使用迭代器訪問集合中的對象,而不需要知道這些對象在集合中是如何表示及存儲的。用戶可以同時(shí)使用多個(gè)迭代器遍歷一個(gè)集合。,經(jīng)典設(shè)計(jì)模式介紹,創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式結(jié)構(gòu)型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,行為型模式1.迭代器模式2.觀察者模式3.策略模式4.命令模式5.職責(zé)鏈模式6.解釋器模式7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,經(jīng)典設(shè)計(jì)模式:觀察者模式,觀察者模式:定義對象間的一種一對多的依賴關(guān)系,當(dāng)一個(gè)對象的狀態(tài)發(fā)生變化時(shí),所有依賴于它的對象都得到通知并被自動更新。應(yīng)用背景:多個(gè)對象都對一個(gè)特殊對象中的數(shù)據(jù)變化感興趣,而且這多個(gè)對象都希望跟蹤那個(gè)特殊對象中的數(shù)據(jù)變化,觀察者模式的實(shí)例,某些尋找工作的人對“求職中心”的職業(yè)需求信息的變化非常關(guān)心,很想跟蹤“求職中心”中職業(yè)需求信息的變化?!扒舐氄摺笨梢宰尅扒舐氈行摹卑炎约旱怯浵聛?,這樣求職中心就會及時(shí)通知她最新的職業(yè)信息需求。,觀察者模式的結(jié)構(gòu),模式的結(jié)構(gòu)中包括四種角色:主題(Subject)具體主題(ConcreteSubject)觀察者(Observer)具體觀察者(ConcreteObserver),觀察者模式的UML圖,觀察者模式的應(yīng)用實(shí)例(1/5),某些尋找工作的人對“求職中心”的職業(yè)需求信息的變化非常關(guān)心,很想跟蹤“求職中心”中職業(yè)需求信息的變化?!扒舐氄摺笨梢宰尅扒舐氈行摹卑炎约旱怯浵聛?,這樣求職中心就會及時(shí)通知她最新的職業(yè)信息需求。,觀察者模式的應(yīng)用實(shí)例(2/5),1主題:Subject.javapublicinterfaceSubjectpublicvoidaddObserver(Observero);publicvoiddeleteObserver(Observero);publicvoidnotifyObservers();publicvoidgiveNewMess();,觀察者模式的應(yīng)用實(shí)例(3/5),2觀察者:Obsever.javapublicinterfaceObserverpublicvoidhearTelephone(StringheardMess);,觀察者模式的應(yīng)用實(shí)例(3/5),3具體主題SeekJobCenter.java_1importjava.util.ArrayList;publicclassSeekJobCenterimplementsSubjectStringmess;booleanchanged;ArrayListpersonList;SeekJobCenter()personList=newArrayList();mess=""changed=false;publicvoidaddObserver(Observero)if(!(personList.contains(o)personList.add(o);publicvoiddeleteObserver(Observero)if(personList.contains(o)personList.remove(o);,觀察者模式的應(yīng)用實(shí)例(4/5),3具體主題SeekJobCenter.java_2publicvoidnotifyObservers()if(changed)for(inti=0;i<personList.size();i+)Observerobserver=personList.get(i);observer.hearTelephone(mess);changed=false;publicvoidgiveNewMess(Stringstr)if(str.equals(mess)changed=false;elsemess=str;changed=true;,觀察者模式的應(yīng)用實(shí)例(5/5),4具體觀察者_(dá)1UniversityStudent.javaimportjava.io.*;publicclassUniverStudentimplementsObserverSubjectsubject;FilemyFile;UniverStudent(Subjectsubject,StringfileName)this.subject=subject;subject.addObserver(this);/使當(dāng)前實(shí)例成為subject所引用的具體主題的觀察者myFile=newFile(fileName);publicvoidhearTelephone(StringheardMess)tryRandomAccessFileout=newRandomAccessFile(myFile,"rw");out.seek(out.length();byteb=heardMess.getBytes();out.write(b);/更新文件中的內(nèi)容System.out.print("我是一個(gè)大學(xué)生,");System.out.println("我向文件"+myFile.getName()+"寫入如下內(nèi)容:");System.out.println(heardMess);catch(IOExceptionexp)System.out.println(exp.toString();,觀察者模式的應(yīng)用實(shí)例(6/5),4具體觀察者_(dá)2HaiGui.javaimportjava.io.*;importjava.util.regex.*;publicclassHaiGuiimplementsObserverSubjectsubject;FilemyFile;HaiGui(Subjectsubject,StringfileName)this.subject=subject;subject.addObserver(this);/使當(dāng)前實(shí)例成為subject所引用的具體主題的觀察者myFile=newFile(fileName);publicvoidhearTelephone(StringheardMess)trybooleanboo=heardMess.contains("java程序員")|heardMess.contains("軟件");if(boo)RandomAccessFileout=newRandomAccessFile(myFile,"rw");out.seek(out.length();byteb=heardMess.getBytes();out.write(b);System.out.print("我是一個(gè)海歸,");System.out.println("我向文件"+myFile.getName()+"寫入如下內(nèi)容:");System.out.println(heardMess);elseSystem.out.println("我是海歸,這次的信息中沒有我需要的信息");catch(IOExceptionexp)System.out.println(exp.toString();,觀察者模式的應(yīng)用實(shí)例(7/5),5應(yīng)用Application.javapublicclassApplicationpublicstaticvoidmain(Stringargs)SeekJobCentercenter=newSeekJobCenter();UniverStudentzhangLin=newUniverStudent(center,"A.txt");HaiGuiwangHao=newHaiGui(center,"B.txt");center.giveNewMess("騰輝公司需要10個(gè)java程序員。");center.notifyObservers();center.giveNewMess("海景公司需要8個(gè)動畫設(shè)計(jì)師。");center.notifyObservers();center.giveNewMess("仁海公司需要9個(gè)電工。");center.notifyObservers();center.giveNewMess("仁海公司需要9個(gè)電工。");center.notifyObservers();,觀察者模式的優(yōu)點(diǎn),觀察模式滿足“開-閉原則”主題接口僅僅依賴于觀察者接口,這樣,我們就可以讓創(chuàng)建具體主題的類也僅僅是依賴于觀察者接口,因此如果增加新的實(shí)現(xiàn)觀察者接口的類,不必修改創(chuàng)建具體主題的類的代碼。同樣,創(chuàng)建具體觀察者的類僅僅依賴于主題接口,如果增加新的實(shí)現(xiàn)主題接口的類,也不必修改創(chuàng)建具體觀察者類的代碼。,經(jīng)典設(shè)計(jì)模式介紹,創(chuàng)建型模式1.抽象工廠模式2.工廠方法模式3.單例模式4.建造者模式5.原型模式結(jié)構(gòu)型模式1.適配器模式2.外觀模式3.橋接模式4.組合模式5.裝飾模式6.享元模式7.代理模式,行為型模式1.迭代器模式2.觀察者模式3.策略模式4.命令模式5.職責(zé)鏈模式6.解釋器模式7.中介者模式8.備忘錄模式9.狀態(tài)模式10.模板方法模式11.訪問者模式,經(jīng)典設(shè)計(jì)模式:策略模式,策略模式:定義一系列算法,把它們一個(gè)個(gè)封裝起來,并且使它們可相互替換。本模式使得算法可獨(dú)立于使用它的客戶而變化。在策略模式中,封裝算法標(biāo)識的接口稱作策略,實(shí)現(xiàn)該接口的類稱作具體策略,策略模式的結(jié)構(gòu),模式的結(jié)構(gòu)中包括三種角色:策略(Strategy)具體策略(ConcreteStrategy)上下文(Context),策略模式的UML圖,策略模式的應(yīng)用實(shí)例(1/5),1策略(Strategy):Computable.javapublicinterfaceComputableStrategypublicabstractdoublecomputeScore(doublea);,策略模式的應(yīng)用實(shí)例(2/5),2具體策略(ConcreteStrategy):StrategyOne.javapublicclassStrategyOneimplementsComputableStrategypublicdoublecomputeScore(doublea)doublescore=0,sum=0;for(inti=0;i<a.length;i+)sum=sum+ai;score=sum/a.length;returnscore;,計(jì)算平均值的方式,策略模式的應(yīng)用實(shí)例(3/5),2具體策略(ConcreteStrategy):StrategyTwo.javapublicclassStrategyTwoimpl