版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
java設(shè)計(jì)模式耿祥義第一章設(shè)計(jì)模式簡(jiǎn)介
1.1什么是設(shè)計(jì)模式
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/20232
每一個(gè)設(shè)計(jì)模式描述一個(gè)在我們周圍不斷重復(fù)發(fā)生的問題,以及該問題的解決方案的核心。這樣,你就能一次一次地使用該方案而不必做重復(fù)勞動(dòng)。1.2設(shè)計(jì)模式的起源Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/20233
軟件領(lǐng)域的設(shè)計(jì)模式起源于建筑學(xué)。1977年,建筑大師Alexander出版了《APatternLanguage:Towns,Building,Construction》一書。受Alexander著作的影響,KentBeck和WardCunningham在1987年舉行的一次面向?qū)ο蟮臅?huì)議上發(fā)表了論文:《在面向?qū)ο缶幊讨惺褂媚J健贰?/p>
1.3GOF之著作Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/20234
目前,被公認(rèn)在設(shè)計(jì)模式領(lǐng)域最具影響力的著作是ErichGamma、RichardHelm、RalphJohnson和JohnVlissides在1994年合作出版的著作:《DesignPatterns:ElementsofReusableObject-OrientedSoftware》(中譯本《設(shè)計(jì)模式:可復(fù)用的面向?qū)ο筌浖幕驹怼坊颉对O(shè)計(jì)模式》),該書被廣大喜愛者昵稱為GOF(GangofFour)之書,被認(rèn)為是學(xué)習(xí)設(shè)計(jì)模式的必讀著作,GOF之書已經(jīng)被公認(rèn)為是設(shè)計(jì)模式領(lǐng)域的奠基之作。1.4學(xué)習(xí)設(shè)計(jì)模式的重要性Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/20235
學(xué)習(xí)設(shè)計(jì)模式不僅可以使我們使用好這些成功的模式,更重要的是可以使我們更加深刻地理解面向?qū)ο蟮脑O(shè)計(jì)思想,非常有利于我們更好地使用面向?qū)ο笳Z言解決設(shè)計(jì)中的問題。
1.5合理使用模式Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/20236
1.正確使用
2.避免教條3.模式挖掘第二章面向?qū)ο蟮膸讉€(gè)基本原則
2.1面向抽象原則Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/20237設(shè)計(jì)一個(gè)類時(shí),不讓該類面向具體的類,而是面向抽象類或接口。第二章面向?qū)ο蟮膸讉€(gè)基本原則
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/20238publicclassCircle{doubler;Circle(doubler){this.r=r;}publicdoublegetArea(){return3.14*r*r;}}publicclassPillar{Circlebottom;doubleheight;Pillar(Circlebottom,doubleheight){this.bottom=bottom;this.height=height;}}定義底面為三角形的柱體?第二章面向?qū)ο蟮膸讉€(gè)基本原則
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/20239publicabstractclassGeometry{publicabstractdoublegetArea();}publicclassPillar{Geometrybottom;doubleheight;Pillar(Circlebottom,doubleheight){this.bottom=bottom;this.height=height;}}2.2開-閉原則Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202310設(shè)計(jì)應(yīng)當(dāng)對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。如果您的設(shè)計(jì)遵守了“開-閉原則”,那么這個(gè)設(shè)計(jì)一定是易維護(hù)的,因?yàn)樵谠O(shè)計(jì)中增加新的模塊時(shí),不必去修改設(shè)計(jì)中的核心模塊。2.3高內(nèi)聚-低耦合原則Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202311如果類中的方法是一組相關(guān)的行為,則稱該類是高內(nèi)聚的,反之稱為低內(nèi)聚的。所謂低耦合就是盡量不要讓一個(gè)類含有太多的其它類的實(shí)例的引用,以避免修改系統(tǒng)的其中一部分會(huì)影響到其它部分。第四章命令模式Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202312命令模式(別名:動(dòng)作,事務(wù))將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤消的操作。CommandPattern(AnotherName:Action,Transaction)Encapsulatearequestasanobject,therebylettingyouparameterizeclientswithdifferentrequests,queueorlogrequests,andsupportundoableoperations.一、概述Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202313在許多設(shè)計(jì)中,經(jīng)常涉及到一個(gè)對(duì)象請(qǐng)求另一個(gè)對(duì)象調(diào)用其方法到達(dá)某種目的。如果請(qǐng)求者不希望或無法直接和被請(qǐng)求者打交道,即不希望或無法含有被請(qǐng)求者的引用,那么就可以使用命令模式。
實(shí)例在軍隊(duì)作戰(zhàn)中,指揮官請(qǐng)求三連偷襲敵人,但是指揮官不希望或無法直接與三連取得聯(lián)系,那么可以將該請(qǐng)求:“三連偷襲敵人”形成一個(gè)“作戰(zhàn)命令”。只要能讓該作戰(zhàn)命令被執(zhí)行,就會(huì)實(shí)現(xiàn)三連偷襲敵人的目的。二、命令模式的結(jié)構(gòu)與使用Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202315模式的結(jié)構(gòu)中包括四種角色:接收者(Receiver)命令(Command)接口具體命令(ConcreteCommand)請(qǐng)求者(Invoker)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202316模式的UML類圖
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202317模式的結(jié)構(gòu)的描述與使用1.接收者(Receiver):CompanyArmy.javapublicclassCompanyArmy{publicvoidsneakAttack(){System.out.println("我們知道如何偷襲敵人,保證完成任務(wù)");}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202318模式的結(jié)構(gòu)的描述與使用2.命令(Command)接口:Command.javapublicinterfaceCommand{publicabstractvoidexecute();}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202319模式的結(jié)構(gòu)的描述與使用3.具體命令(ConcreteCommand)ConcreteCommand.javapublicclassConcreteCommandimplementsCommand{CompanyArmyarmy;//含有接收者的引用ConcreteCommand(CompanyArmyarmy){this.army=army;}publicvoidexecute(){//封裝著指揮官的請(qǐng)求army.sneakAttack();//偷襲敵人
}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202320模式的結(jié)構(gòu)的描述與使用4.請(qǐng)求者(Invoker)ArmySuperior.javapublicclassArmySuperior{Commandcommand;//用來存放具體命令的引用publicvoidsetCommand(Commandcommand){mand=command;}publicvoidstartExecuteCommand(){
//讓具體命令執(zhí)行execute()方法command.execute();}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202321模式的結(jié)構(gòu)的描述與使用5.應(yīng)用Application.javapublicclassApplication{publicstaticvoidmain(Stringargs[]){CompanyArmy三連=newCompanyArmy();Commandcommand=newConcreteCommand(三連);ArmySuperior指揮官=newArmySuperior();指揮官.setCommand(command);指揮官.startExecuteCommand();}}三、命令模式的優(yōu)點(diǎn)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202322在命令模式中,請(qǐng)求者(Invoker)不直接與接收者(Receiver)交互,即請(qǐng)求者(Invoker)不包含接收者(Receiver)的引用,因此徹底消除了彼此之間的耦合。命令模式滿足“開-閉原則”。如果增加新的具體命令和該命令的接受者,不必修改調(diào)用者的代碼,調(diào)用者就可以使用新的命令對(duì)象;反之,如果增加新的調(diào)用者,不必修改現(xiàn)有的具體命令和接受者,新增加的調(diào)用者就可以使用已有的具體命令。四、應(yīng)用舉例模擬帶控制開關(guān)的小電器。該電器上有四個(gè)開關(guān),兩個(gè)一組,其中一組負(fù)責(zé)打開、關(guān)閉小電器上的照明燈,另一組負(fù)責(zé)打開、關(guān)閉小電器上的攝像頭。第五章觀察者模式Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202324觀察者模式(別名:依賴,發(fā)布-訂閱)定義對(duì)象間的一種一對(duì)多的依賴關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生變化時(shí),所有依賴于它的對(duì)象都得到通知并被自動(dòng)更新。ObserverPattern(AnotherName:Dependents,Publish-Subscribe)Defineaone-to-manydependencybetweenobjectssothatwhenoneobjectchangesstate,allitsdependentsarenotifiedandupdatedautomatically..一、概述Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202325
在許多設(shè)計(jì)中,經(jīng)常涉及到多個(gè)對(duì)象都對(duì)一個(gè)特殊對(duì)象中的數(shù)據(jù)變化感興趣,而且這多個(gè)對(duì)象都希望跟蹤那個(gè)特殊對(duì)象中的數(shù)據(jù)變化。
實(shí)例某些尋找工作的人對(duì)“求職中心”的職業(yè)需求信息的變化非常關(guān)心,很想跟蹤“求職中心”中職業(yè)需求信息的變化?!扒舐氄摺笨梢宰尅扒舐氈行摹卑炎约旱怯浵聛?,這樣求職中心就會(huì)及時(shí)通知她最新的職業(yè)信息需求。二、模式的結(jié)構(gòu)與使用Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202327觀察者模式的結(jié)構(gòu)中包括四種角色:主題(Subject)觀察者(Observer)具體主題(ConcreteSubject)具體觀察者(ConcreteObserver)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202328模式的UML類圖
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202329模式的結(jié)構(gòu)的描述與使用1.主題:Subject.javapublicinterfaceSubject{publicvoidaddObserver(Observero);publicvoiddeleteObserver(Observero);publicvoidnotifyObservers();}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202330模式的結(jié)構(gòu)的描述與使用2.觀察者:Obsever.javapublicinterfaceObserver{publicvoidhearTelephone(StringheardMess);}
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202331模式的結(jié)構(gòu)的描述與使用3.具體主題SeekJobCenter.java_1importjava.util.ArrayList;publicclassSeekJobCenterimplementsSubject{Stringmess;booleanchanged;ArrayList<Observer>personList;SeekJobCenter(){personList=newArrayList<Observer>();mess="";changed=false;}publicvoidaddObserver(Observero){if(!(personList.contains(o)))personList.add(o);}publicvoiddeleteObserver(Observero){if(personList.contains(o))personList.remove(o);}
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202332模式的結(jié)構(gòu)的描述與使用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;else{mess=str;changed=true;}}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202333模式的結(jié)構(gòu)的描述與使用4.具體觀察者_(dá)1UniversityStudent.javaimportjava.io.*;publicclassUniverStudentimplementsObserver{Subjectsubject;FilemyFile;UniverStudent(Subjectsubject,StringfileName){this.subject=subject;subject.addObserver(this);//使當(dāng)前實(shí)例成為subject所引用的具體主題的觀察者myFile=newFile(fileName);}publicvoidhearTelephone(StringheardMess){try{RandomAccessFileout=newRandomAccessFile(myFile,"rw");out.seek(out.length());byte[]b=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());}}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202334模式的結(jié)構(gòu)的描述與使用4.具體觀察者_(dá)2HaiGui.java
importjava.io.*;importjava.util.regex.*;publicclassHaiGuiimplementsObserver{Subjectsubject;FilemyFile;HaiGui(Subjectsubject,StringfileName){this.subject=subject;subject.addObserver(this);//使當(dāng)前實(shí)例成為subject所引用的具體主題的觀察者myFile=newFile(fileName);}publicvoidhearTelephone(StringheardMess){try{booleanboo=heardMess.contains("java程序員")||heardMess.contains("軟件");if(boo){RandomAccessFileout=newRandomAccessFile(myFile,"rw");out.seek(out.length());byte[]b=heardMess.getBytes();out.write(b);System.out.print("我是一個(gè)海歸,");System.out.println("我向文件"+myFile.getName()+"寫入如下內(nèi)容:");System.out.println(heardMess);}else{System.out.println("我是海歸,這次的信息中沒有我需要的信息");}}catch(IOExceptionexp){System.out.println(exp.toString());}}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202335模式的結(jié)構(gòu)的描述與使用5.應(yīng)用Application.javapublicclassApplication{publicstaticvoidmain(Stringargs[]){SeekJobCentercenter=newSeekJobCenter();UniverStudentzhangLin=newUniverStudent(center,"A.txt");HaiGuiwangHao=newHaiGui(center,"B.txt");center.giveNewMess("騰輝公司需要10個(gè)java程序員。");center.notifyObservers();center.giveNewMess("海景公司需要8個(gè)動(dòng)畫設(shè)計(jì)師。");center.notifyObservers();center.giveNewMess("仁海公司需要9個(gè)電工。");center.notifyObservers();center.giveNewMess("仁海公司需要9個(gè)電工。");center.notifyObservers();}三、觀察者模式的優(yōu)點(diǎn)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202336具體主題和具體觀察者是松耦合關(guān)系。由于主題(Subject)接口僅僅依賴于觀察者(Observer)接口,因此具體主題只是知道它的觀察者是實(shí)現(xiàn)觀察者(Observer)接口的某個(gè)類的實(shí)例,但不需要知道具體是哪個(gè)類。同樣,由于觀察者僅僅依賴于主題(Subject)接口,因此具體觀察者只是知道它依賴的主題是實(shí)現(xiàn)主題(subject)接口的某個(gè)類的實(shí)例,但不需要知道具體是哪個(gè)類。觀察模式滿足“開-閉原則”。主題(Subject)接口僅僅依賴于觀察者(Observer)接口,這樣,我們就可以讓創(chuàng)建具體主題的類也僅僅是依賴于觀察者(Observer)接口,因此如果增加新的實(shí)現(xiàn)觀察者(Observer)接口的類,不必修改創(chuàng)建具體主題的類的代碼。同樣,創(chuàng)建具體觀察者的類僅僅依賴于主題(Observer)接口,如果增加新的實(shí)現(xiàn)主題(Subject)接口的類,也不必修改創(chuàng)建具體觀察者類的代碼。四、應(yīng)用舉例指揮部希望按時(shí)得到水文站測(cè)量到的關(guān)于水流的信息,比如流量、流速等。第六章裝飾模式Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202338裝飾模式(別名:包裝器)動(dòng)態(tài)地給對(duì)象添加一些額外的職責(zé)。就功能來說裝飾模式相比生成子類更為靈活。DecoratorPattern(AnotherName:Wrapper)Attachadditionalresponsibilitiestoanobjectdynamically.Decoratorsprovideaflexiblealternativetosubclassingforextendingfunctionality.一、概述Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202339裝飾模式是動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能,而不需要改變?cè)碱惔a的一種成熟模式。在裝飾模式中,“具體組件”類和“具體裝飾”類是該模式中的最重要的兩個(gè)角色。實(shí)例
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202340假設(shè)系統(tǒng)中有一個(gè)Bird抽象類以及Bird類的一個(gè)子類:Sparrow。Sparrow類實(shí)現(xiàn)了Bird類的fly方法,使得Sparrow類創(chuàng)建的對(duì)象調(diào)用fly方法能連續(xù)飛行100米?,F(xiàn)在用戶需要兩種鳥,必須分別能連續(xù)飛行150米和200米。二、裝飾模式模式的結(jié)構(gòu)與使用
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202341裝飾模式的結(jié)構(gòu)中包括四種角色:抽象組件(Component)具體組件(ConcreteComponent)裝飾(Decorator)具體裝飾(ConcreteDecotator)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202342裝飾模式的UML類圖
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202343裝飾模式的結(jié)構(gòu)的描述與使用1.抽象組件:Bird.javapublicabstractclassBird{publicabstractintfly();}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202344裝飾模式的結(jié)構(gòu)的描述與使用2.具體組件:Sparrow.javapublicclassSparrowextendsBird{publicfinalintDISTANCE=100;publicintfly(){returnDISTANCE;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202345裝飾模式的結(jié)構(gòu)的描述與使用3.裝飾(Decorator):
Decorator.javapublicabstractclassDecoratorextendsBird{protectedBirdbird;publicDecorator(){}publicDecorator(Birdbird){this.bird=bird;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202346裝飾模式的結(jié)構(gòu)的描述與使用4.具體裝飾(ConcreteDecotator):
SparrowDecorator.javapublicclassSparrowDecoratorextendsDecorator{publicfinalintDISTANCE=50;//eleFly方法能飛50米SparrowDecorator(Birdbird){super(bird);}publicintfly(){intdistance=0;distance=bird.fly()+eleFly();returndistance;}privateinteleFly(){//裝飾者新添加的方法returnDISTANCE;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202347裝飾模式的結(jié)構(gòu)的描述與使用5.應(yīng)用Application.java
publicclassApplication{publicvoidneedBird(Birdbird){intflyDistance=bird.fly();System.out.println("這只鳥能飛行"+flyDistance+"米");}publicstaticvoidmain(Stringargs[]){Applicationclient=newApplication();Birdsparrow=newSparrow();BirdsparrowDecorator1=newSparrowDecorator(sparrow);BirdsparrowDecorator2=newSparrowDecorator(sparrowDecorator1);client.needBird(sparrowDecorator1);client.needBird(sparrowDecorator2);}}三、裝飾模式的優(yōu)點(diǎn)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202348
被裝飾者和裝飾者是松耦合關(guān)系。由于裝飾(Decorator)僅僅依賴于抽象組件(Component),因此具體裝飾只知道它要裝飾的對(duì)象是抽象組件的某一個(gè)子類的實(shí)例,但不需要知道是哪一個(gè)具體子類。裝飾模式滿足“開-閉原則”。不必修改具體組件,就可以增加新的針對(duì)該具體組件的具體裝飾。可以使用多個(gè)具體裝飾來裝飾具體組件的實(shí)例。四、應(yīng)用舉例當(dāng)前系統(tǒng)已有一個(gè)抽象類ReadWord,該類有一個(gè)抽象方法readWord(),另外還有一個(gè)ReadWord類的子類ReadEnglishWord,該類的readWord()方法可以讀取一個(gè)由英文單詞構(gòu)成的文本文件word.txt。系統(tǒng)已有類的類圖如圖6.11所示。目前已有一些客戶在使用該系統(tǒng),并使用ReadWord類的對(duì)象調(diào)用readWord()方法讀取文件中的單詞。ReadWord+readWord(File)ReadEnglishWord+readWord(File)四、應(yīng)用舉例現(xiàn)有部分用戶希望使用ReadWord類的對(duì)象調(diào)用readWord()方法讀取文件word.txt中的單詞,并希望同時(shí)也能得到該單詞的漢語解釋,也有一些用戶希望不僅能得到該單詞漢語解釋也能得到該單詞的英文例句。要求不允許修改現(xiàn)有系統(tǒng)的代碼以及word.txt文件,對(duì)系統(tǒng)進(jìn)行擴(kuò)展以滿足用戶需求。第七章策略模式Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202351策略模式(別名:政策)定義一系列算法,把它們一個(gè)個(gè)封裝起來,并且使它們可相互替換。本模式使得算法可獨(dú)立于使用它的客戶而變化。StrategyPattern(AnotherName:Policy)Defineafamilyofalgorithms,encapsulateeachone,andmaketheminterchangeable.Strategyletsthealgorithmvaryindependentlyfromclientsthatuseit.一、概述Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202352策略模式是處理算法的不同變體的一種成熟模式,策略模式通過接口或抽象類封裝算法的標(biāo)識(shí),即在接口中定義一個(gè)抽象方法,實(shí)現(xiàn)該接口的類將實(shí)現(xiàn)接口中的抽象方法。在策略模式中,封裝算法標(biāo)識(shí)的接口稱作策略,實(shí)現(xiàn)該接口的類稱作具體策略。實(shí)例
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202353策略模式是處理算法的不同變體的一種成熟模式,策略模式通過接口或抽象類封裝算法的標(biāo)識(shí),即在接口中定義一個(gè)抽象方法,實(shí)現(xiàn)該接口的類將實(shí)現(xiàn)接口中的抽象方法。在策略模式中,封裝算法標(biāo)識(shí)的接口稱作策略,實(shí)現(xiàn)該接口的類稱作具體策略。二、策略模式的結(jié)構(gòu)與使用Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202354策略模式的結(jié)構(gòu)中包括三種角色:策略(Strategy)具體策略(ConcreteStrategy)上下文(Context)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202355策略模式的UML類圖
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202356策略模式的結(jié)構(gòu)的描述與使用1.策略(Strategy):Computable.javapublicinterfaceComputableStrategy{publicabstractdoublecomputeScore(double[]a);}
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202357策略模式的結(jié)構(gòu)的描述與使用2.具體策略(ConcreteStrategy):StrategyOne.javapublicclassStrategyOneimplementsComputableStrategy{publicdoublecomputeScore(double[]a){doublescore=0,sum=0;for(inti=0;i<a.length;i++){sum=sum+a[i];}score=sum/a.length;returnscore;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202358策略模式的結(jié)構(gòu)的描述與使用2.具體策略(ConcreteStrategy):StrategyTwo.javapublicclassStrategyTwoimplementsComputableStrategy{publicdoublecomputeScore(double[]a){doublescore=0,multi=1;intn=a.length;for(inti=0;i<a.length;i++){multi=multi*a[i];}score=Math.pow(multi,1.0/n);returnscore;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202359策略模式的結(jié)構(gòu)的描述與使用2.具體策略(ConcreteStrategy):StrategyThree.javaimportjava.util.Arrays;publicclassStrategyThreeimplementsComputableStrategy{publicdoublecomputeScore(double[]a){if(a.length<=2)return0;doublescore=0,sum=0;Arrays.sort(a);for(inti=1;i<a.length-1;i++){sum=sum+a[i];}score=sum/(a.length-2);returnscore;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202360策略模式的結(jié)構(gòu)的描述與使用3.上下文:GymnasticsGame.javapublicclassGymnasticsGame{ComputableStrategystrategy;publicvoidsetStrategy(ComputableStrategystrategy){this.strategy=strategy;}publicdoublegetPersonScore(double[]a){if(strategy!=null)returnputeScore(a);elsereturn0;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202361策略模式的結(jié)構(gòu)的描述與使用4.應(yīng)用:Application.java_1
publicclassApplication{publicstaticvoidmain(Stringargs[]){GymnasticsGamegame=newGymnasticsGame();game.setStrategy(newStrategyOne());Personzhang=newPerson();zhang.setName("張三");double[]a={9.12,9.25,8.87,9.99,6.99,7.88};Personli=newPerson();li.setName("李四");double[]b={9.15,9.26,8.97,9.89,6.97,7.89};zhang.setScore(game.getPersonScore(a));li.setScore(game.getPersonScore(b));System.out.println("使用算術(shù)平均值方案:");System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());game.setStrategy(newStrategyTwo());zhang.setScore(game.getPersonScore(a));li.setScore(game.getPersonScore(b));System.out.println("使用幾何平均值方案:");System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202362策略模式的結(jié)構(gòu)的描述與使用4.應(yīng)用:Application.java_2
game.setStrategy(newStrategyThree());zhang.setScore(game.getPersonScore(a));li.setScore(game.getPersonScore(b));System.out.println("使用(去掉最高、最底)算術(shù)平均值方案:");System.out.printf("%s最后得分:%5.3f%n",zhang.getName(),zhang.getScore());System.out.printf("%s最后得分:%5.3f%n",li.getName(),li.getScore());}}classPerson{Stringname;doublescore;publicvoidsetScore(doublet){score=t;}publicvoidsetName(Strings){name=s;}publicdoublegetScore(){returnscore;}publicStringgetName(){returnname;}}三、策略模式的優(yōu)點(diǎn)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202363
上下文(Context)和具體策略(ConcreteStrategy)是松耦合關(guān)系。因此上下文只知道它要使用某一個(gè)實(shí)現(xiàn)Strategy接口類的實(shí)例,但不需要知道具體是哪一個(gè)類。策略模式滿足“開-閉原則”。當(dāng)增加新的具體策略時(shí),不需要修改上下文類的代碼,上下文就可以引用新的具體策略的實(shí)例。第八章適配器模式Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202364適配器模式(別名:包裝器)將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。AdapterPattern(AnotherName:Wrapper)Converttheinterfaceofaclassintoanotherinterfaceclientsexpect.Adapterletsclassesworktogetherthatcouldn'totherwisebecauseofincompatibleinterfaces.一、概述Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202365
適配器模式是將一個(gè)類的接口(被適配者)轉(zhuǎn)換成客戶希望的另外一個(gè)接口(目標(biāo))的成熟模式,該模式中涉及有目標(biāo)、被適配者和適配器。適配器模式的關(guān)鍵是建立一個(gè)適配器,這個(gè)適配器實(shí)現(xiàn)了目標(biāo)接口并包含有被適配者的引用。實(shí)例
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202366用戶已有一個(gè)兩相的插座,但最近用戶又有了一個(gè)新的三相插座。用戶現(xiàn)在已經(jīng)有一臺(tái)洗衣機(jī)和一臺(tái)電視機(jī),洗衣機(jī)按著三相插座的標(biāo)準(zhǔn)配有三相插頭,而電視機(jī)按著兩相插座的標(biāo)準(zhǔn)配有兩相插頭。現(xiàn)在用戶想用新的三相插座來使用洗衣機(jī)和電視機(jī)。二、適配器模式的結(jié)構(gòu)與使用
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202367模式的結(jié)構(gòu)中包括三種角色:目標(biāo)(Target)被適配者(Adaptee)適配器(Adapter)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202368模式的UML類圖
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202369模式的結(jié)構(gòu)的描述與使用1.目標(biāo)(Target):ThreeElectricOutlet.javapublicinterfaceThreeElectricOutlet{publicabstractvoidconnectElectricCurrent();}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202370模式的結(jié)構(gòu)的描述與使用2.被適配者(Adaptee):TwoElectricOutlet.javapublicinterfaceTwoElectricOutlet{publicabstractvoidconnectElectricCurrent();}
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202371模式的結(jié)構(gòu)的描述與使用3.適配器(Adapter)
TreeElectricAdapter.javapublicclassTreeElectricAdapterimplementsThreeElectricOutlet{TwoElectricOutletoutlet;TreeElectricAdapter(TwoElectricOutletoutlet){this.outlet=outlet;}publicvoidconnectElectricCurrent(){outlet.connectElectricCurrent();}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202372模式的結(jié)構(gòu)的描述與使用4.應(yīng)用Application.java_1
publicclassApplication{publicstaticvoidmain(Stringargs[]){ThreeElectricOutletoutlet;Washwash=newWash();outlet=wash;System.out.println("使用三相插座接通電流:");outlet.connectElectricCurrent();TVtv=newTV();TreeElectricAdapteradapter=newTreeElectricAdapter(tv);outlet=adapter;System.out.println("使用三相插座接通電流:");outlet.connectElectricCurrent();}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202373模式的結(jié)構(gòu)的描述與使用4.應(yīng)用Application.java_2
classWashimplementsThreeElectricOutlet{Stringname;Wash(){name="黃河洗衣機(jī)";}Wash(Strings){name=s;}publicvoidconnectElectricCurrent(){turnOn();}publicvoidturnOn(){System.out.println(name+"開始洗衣物。");}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202374模式的結(jié)構(gòu)的描述與使用4.應(yīng)用Application.java_3
classTVimplementsTwoElectricOutlet{Stringname;TV(){name="長(zhǎng)江電視機(jī)";}TV(Strings){name=s;}publicvoidconnectElectricCurrent(){turnOn();}publicvoidturnOn(){System.out.println(name+"開始播放節(jié)目。");}}三、適配器模式的優(yōu)點(diǎn)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202375目標(biāo)(Target)和被適配者(Adaptee)是完全解耦的關(guān)系。適配器模式滿足“開-閉原則”。當(dāng)添加一個(gè)實(shí)現(xiàn)Adaptee接口的新類時(shí),不必修改Adapter,Adapter就能對(duì)這個(gè)新類的實(shí)例進(jìn)行適配。第九章責(zé)任鏈模式Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202376責(zé)任鏈模式使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免請(qǐng)求的發(fā)送者和接收者之間的耦合關(guān)系。將這些對(duì)象連成一條鏈,并沿著這條鏈傳遞該請(qǐng)求,直到有一個(gè)對(duì)象處理它為止。ChainofResponsibilityPatternAvoidcouplingthesenderofarequesttoitsreceiverbygivingmorethanoneobjectachancetohandletherequest.Chainthereceivingobjectsandpasstherequestalongthechainuntilanobjecthandlesit.一、概述Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202377責(zé)任鏈模式是使用多個(gè)對(duì)象處理用戶請(qǐng)求的成熟模式,責(zé)任鏈模式的關(guān)鍵是將用戶的請(qǐng)求分派給許多對(duì)象,這些對(duì)象被組織成一個(gè)責(zé)任鏈,即每個(gè)對(duì)象含有后繼對(duì)象的引用,并要求責(zé)任鏈上的每個(gè)對(duì)象,如果能處理用戶的請(qǐng)求,就做出處理,不再將用戶的請(qǐng)求傳遞給責(zé)任鏈上的下一個(gè)對(duì)象;如果不能處理用戶的請(qǐng)求,就必須將用戶的請(qǐng)求傳遞給責(zé)任鏈上的下一個(gè)對(duì)象。一、實(shí)例Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202378用戶提交一個(gè)人的身份證號(hào)碼,想知道該人是在北京、上?;蛘咛旖蚓幼 6?、責(zé)任鏈模式的結(jié)構(gòu)與使用
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202379模式的結(jié)構(gòu)中包括兩種角色:處理者(Handler)具體處理者(ConcreteHandler)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202380模式的UML類圖
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202381模式的結(jié)構(gòu)的描述與使用1.處理者(Handler):Handler.javapublicinterfaceHandler{publicabstractvoidhandleRequest(Stringnumber);publicabstractvoidsetNextHandler(Handlerhandler);}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202382模式的結(jié)構(gòu)的描述與使用2.具體處理者(ConcreteHandler)_1:Beijing.javaimportjava.util.*;publicclassBeijingimplementsHandler{privateHandlerhandler;privateArrayList<String>numberList;Beijing(){numberList=newArrayList<String>();numberList.add("11129812340930034");numberList.add("10120810340930632");numberList.add("22029812340930034");numberList.add("32620810340930632");}publicvoidhandleRequest(Stringnumber){if(numberList.contains(number))System.out.println("該人在北京居住");else{System.out.println("該人不在北京居住");if(handler!=null)handler.handleRequest(number);}}publicvoidsetNextHandler(Handlerhandler){this.handler=handler;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202383模式的結(jié)構(gòu)的描述與使用2.具體處理者(ConcreteHandler)_2:Shanghai.javaimportjava.util.*;publicclassShanghaiimplementsHandler{privateHandlerhandler;privateArrayList<String>numberList;Shanghai(){numberList=newArrayList<String>();numberList.add("34529812340930034");numberList.add("98720810340430632");numberList.add("36529812340930034");numberList.add("77720810340930632");}publicvoidhandleRequest(Stringnumber){if(numberList.contains(number))System.out.println("該人在上海居住");else{System.out.println("該人不在上海居住");if(handler!=null)handler.handleRequest(number);}}publicvoidsetNextHandler(Handlerhandler){this.handler=handler;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202384模式的結(jié)構(gòu)的描述與使用2.具體處理者(ConcreteHandler)_3:Tianjin.javaimportjava.util.*;publicclassTianjinimplementsHandler{privateHandlerhandler;privateArrayList<String>numberList;Tianjin(){numberList=newArrayList<String>();numberList.add("10029812340930034");numberList.add("20020810340430632");numberList.add("30029812340930034");numberList.add("50020810340930632");}publicvoidhandleRequest(Stringnumber){if(numberList.contains(number))System.out.println("該人在天津居住");else{System.out.println("該人不在天津居住");if(handler!=null)handler.handleRequest(number);}}publicvoidsetNextHandler(Handlerhandler){this.handler=handler;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202385模式的結(jié)構(gòu)的描述與使用3.應(yīng)用Application.java
publicclassApplication{privateHandlerbeijing,shanghai,tianjin;publicvoidcreateChain(){beijing=newBeijing();shanghai=newShanghai();tianjin=newTianjin();beijing.setNextHandler(shanghai);shanghai.setNextHandler(tianjin);}publicvoidreponseClient(Stringnumber){beijing.handleRequest(number);}publicstaticvoidmain(Stringargs[]){Applicationapplication=newApplication();application.createChain();application.reponseClient("77720810340930632");;}}三、責(zé)任鏈模式的優(yōu)點(diǎn)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202386責(zé)任鏈中的對(duì)象只和自己的后繼是低耦合關(guān)系,和其他對(duì)象毫無關(guān)聯(lián),這使得編寫處理者對(duì)象以及創(chuàng)建責(zé)任鏈變得非常容易。使用責(zé)任鏈的用戶不必知道處理者的信息,用戶不會(huì)知道到底是哪個(gè)對(duì)象處理了它的請(qǐng)求。四、應(yīng)用舉例Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202387設(shè)計(jì)一個(gè)類,該類創(chuàng)建的對(duì)象用int型數(shù)據(jù)計(jì)算階乘,特點(diǎn)是占用內(nèi)存小,計(jì)算速度快;設(shè)計(jì)一個(gè)類,該類創(chuàng)建的對(duì)象用long型數(shù)據(jù)計(jì)算階乘,特點(diǎn)是能計(jì)算更大整數(shù)的階乘;設(shè)計(jì)一個(gè)類,該類創(chuàng)建的對(duì)象用BigInteger型數(shù)據(jù)計(jì)算階乘,特點(diǎn)是能計(jì)算任意大整數(shù)的階乘;要求用責(zé)任鏈模式將上面的對(duì)象組成一個(gè)責(zé)任鏈,要求責(zé)任鏈上對(duì)象的順序是:首先使用int型數(shù)據(jù)計(jì)算階乘的對(duì)象,然后是使用long型數(shù)據(jù)計(jì)算階乘的對(duì)象,最后是使用BigInteger對(duì)象計(jì)算階乘對(duì)象。第十章外觀模式Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202388外觀模式為系統(tǒng)中的一組接口提供一個(gè)一致的界面,F(xiàn)a?ade模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。ChainofResponsibilityPatternProvideaunifiedinterfacetoasetofinterfacesinasubsystem.Facadedefinesahigher-levelinterfacethatmakesthesubsystemeasiertouse.一、概述Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202389
外觀模式是簡(jiǎn)化用戶和子系統(tǒng)進(jìn)行交互的成熟模式,外觀模式的關(guān)鍵是為子系統(tǒng)提供一個(gè)稱作外觀的類,該外觀類的實(shí)例負(fù)責(zé)和子系統(tǒng)中類的實(shí)例打交道。當(dāng)用戶想要和子系統(tǒng)中的若干個(gè)類的實(shí)例打交道時(shí),可以代替地和子系統(tǒng)的外觀類的實(shí)例打交道。
一、應(yīng)用實(shí)例Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202390
郵政系統(tǒng)負(fù)責(zé)郵寄包裹的子系統(tǒng)包含Check、Weight和Transport類。Check類的實(shí)例負(fù)責(zé)對(duì)包裹進(jìn)行安全檢查,Weight類的實(shí)例負(fù)責(zé)根據(jù)包裹的重量計(jì)算郵資,Transport類的實(shí)例負(fù)責(zé)為包裹選擇運(yùn)輸工具。一個(gè)要郵寄的包裹的用戶如果直接和負(fù)責(zé)郵寄包裹的子系統(tǒng)的類打交道就會(huì)非常不方便。
三、應(yīng)用實(shí)例Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202391
報(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é)對(duì)廣告進(jìn)行排版。使用外觀模式簡(jiǎn)化用戶和上述子系統(tǒng)所進(jìn)行的交互。二、外觀模式的結(jié)構(gòu)與使用Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202392模式的結(jié)構(gòu)中包括兩種角色:子系統(tǒng)(Subsystem)外觀(Facade)Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202393模式的UML類圖
Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202394模式的結(jié)構(gòu)的描述與使用1.子系統(tǒng)(Subsystem)_1
:CheckWord.javapublicclassCheckWord{publicfinalintbasicAmount=85;Stringadvertisement;intamount;publicCheckWord(Stringadvertisement){this.advertisement=advertisement;}publicvoidsetChargeAmount(){amount=advertisement.length()+basicAmount;//計(jì)算出計(jì)費(fèi)字符數(shù)目}publicintgetAmount(){returnamount;}}Java設(shè)計(jì)模式Java設(shè)計(jì)模式7/20/202395模式的結(jié)構(gòu)的描述與使用1.子系統(tǒng)(Subsystem)_2
:Charge.javapublicclassCharge{publicfinalintbasicCharge=12;CheckWordcheckWord;Charge(CheckWordcheckWord){this.checkWord=checkWord;}publicvoidgiveCharge(){intcharge=checkWord.getAmount()*basicCharge;System.out.println("廣告費(fèi)用:"+charge+"元");}}
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 六年級(jí)第一學(xué)期教學(xué)計(jì)劃范文合集三篇
- 九年級(jí)化學(xué)教學(xué)計(jì)劃范文錦集7篇
- 銷售部年度工作計(jì)劃
- 師德師風(fēng)的教師演講稿模板5篇
- 人壽保險(xiǎn)公司實(shí)習(xí)報(bào)告合集六篇
- 關(guān)于年會(huì)策劃方案范文合集6篇
- 大學(xué)生頂崗實(shí)習(xí)周記錦集六篇
- 政府績(jī)效評(píng)估 課件 蔡立輝 第6-10章 政府績(jī)效評(píng)估的結(jié)果應(yīng)用與改進(jìn) -政府績(jī)效評(píng)估在當(dāng)代中國(guó)的推進(jìn)
- 2010年高考一輪復(fù)習(xí)教案:必修1 第四章 非金屬及其化合物 全程教學(xué)案
- 2025年農(nóng)林牧漁專用儀器儀表項(xiàng)目發(fā)展計(jì)劃
- 2025中國(guó)電信山東青島分公司校園招聘高頻重點(diǎn)提升(共500題)附帶答案詳解
- 2025年八省聯(lián)考高考語文作文真題及參考范文
- 新課標(biāo)(水平三)體育與健康《籃球》大單元教學(xué)計(jì)劃及配套教案(18課時(shí))
- 開題報(bào)告-鑄牢中華民族共同體意識(shí)的學(xué)校教育研究
- 計(jì)件工勞務(wù)合同范例
- 2024年公交車開通儀式講話例文(4篇)
- 2024-2025學(xué)年八年級(jí)上冊(cè)物理 第五章 透鏡以及其應(yīng)用 測(cè)試卷(含答案)
- 《自理理論orem》課件
- 2024年浙江省杭州市下城區(qū)教育局所屬事業(yè)單位招聘學(xué)科拔尖人才10人歷年管理單位遴選500模擬題附帶答案詳解
- 研發(fā)項(xiàng)目管理培訓(xùn)課件講解
- 2024-2030年中國(guó)膏劑(膏方)行業(yè)競(jìng)爭(zhēng)狀況及營(yíng)銷前景預(yù)測(cè)報(bào)告版
評(píng)論
0/150
提交評(píng)論