




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第一九章組合模式一九.一問題地提出一九.二組合模式一九.三深入理解組合模式一九.四應(yīng)用探究一九.一問題地提出如何行描述呢?很明顯文件樹形結(jié)構(gòu)節(jié)點可分為兩類:一類是文件葉子節(jié)點,無后繼節(jié)點;一類是間目錄節(jié)點,有后繼節(jié)點。因此可得具體代碼如下所示。一.文件節(jié)點類FileLeafclassFileLeaf{ StringfileName; publicFileLeaf(StringfileName){ this.fileName=fileName; } publicvoiddisplay(){ System.out.println(fileName); }}二.間目錄節(jié)點類DirectNodeclassDirectNode{ StringnodeName; publicDirectNode(StringnodeName){ this.nodeName=nodeName; } ArrayList<DirectNode>nodeList=newArrayList(); //后繼子目錄集合 ArrayList<FileLeaf>leafList=newArrayList(); //當(dāng)前目錄文件集合 publicvoidaddNode(DirectNodenode){ //添加下一級子目錄 nodeList.add(node); } publicvoidaddLeaf(FileLeafleaf){ //添加本級文件 leafList.add(leaf); } publicvoiddisplay(){ //從本級目錄開始顯示 for(inti=零;i<leafList.size();i++){ //先顯示文件 leafList.get(i).display(); } for(inti=零;i<nodeList.size();i++){ //再顯示子目錄 System.out.println(nodeList.get(i).nodeName); nodeList.get(i).display(); } }}三.一個簡單地測試類publicclassTest{ publicstaticvoidcreateTree(DirectNodenode){ Filef=newFile(node.nodeName); Filef二[]=f.listFiles(); for(inti=零;i<f二.length;i++){ if(f二[i].isFile()){ FileLeafl=newFileLeaf(f二[i].getAbsolutePath()); node.addLeaf(l); } if(f二[i].isDirectory()){ DirectNodenode二=newDirectNode(f二[i].getAbsolutePath()); node.addNode(node二); createTree(node二); //遞歸調(diào)用生成樹結(jié)構(gòu) } } } publicstaticvoidmain(String[]args){ DirectNodestart=newDirectNode("d://data");//創(chuàng)建該目錄地樹形結(jié)構(gòu)集合 createTree(start); //創(chuàng)建過程 start.display(); //顯示過程,驗證創(chuàng)建是否正確 }}那么有沒有更好地方式完成上述功能,結(jié)構(gòu)更優(yōu)雅呢?組合模式就是解決樹形結(jié)構(gòu)問題強有力地設(shè)計工具。由圖一二-一可知:根目錄是由兩個子目錄組成地,第一個子目錄由兩個文件組成,第二個子目錄由兩個文件組成,因此樹形形式也可以叫做組合形式。在一二-一,把節(jié)點分為葉子節(jié)點與目錄節(jié)點,它們是孤立地。其實只要思維再前一步,就會發(fā)生質(zhì)地變化。那就是把葉子節(jié)點與目錄節(jié)點都看成相同質(zhì)地節(jié)點,只不過目錄節(jié)點后繼節(jié)點不為空,而葉子節(jié)點后繼節(jié)點為null。這樣就能夠?qū)湫谓Y(jié)構(gòu)地所有節(jié)點執(zhí)行相同地操作,這也即是組合模式地最大特點。一.定義抽象節(jié)點類NodeabstractclassNode{ protectedStringname; publicNode(Stringname){ =name; } publicvoidaddNode(Nodenode)throwsException{ thrownewException("Invalidexception"); } abstractvoiddisplay();} 該類是葉子節(jié)點與目錄節(jié)點地父類,節(jié)點名稱是name。其主要包括兩類方法:一類是所有節(jié)點具有相同形式,不同內(nèi)容地方法,這類方法要定義成抽象方法,如display();一類方法是目錄節(jié)點需要重寫,葉子節(jié)點勿需重寫地方法,相當(dāng)于為葉子節(jié)點提供了默認實現(xiàn),如addNode()方法,因為葉子對象沒有該功能,所以可以通過拋出異常防止葉子節(jié)點無效調(diào)用該方法。二.文件葉子結(jié)點類FileNodeclassFileNodeextendsNode{ publicFileNode(Stringname){ super(name); } publicvoiddisplay(){ System.out.println(name); } }三.目錄節(jié)點類DirectNodeclassDirectNodeextendsNode{ privateArrayList<Node>nodeList=newArrayList(); publicDirectNode(Stringname){ super(name); } publicvoidaddNode(Nodenode)throwsException{ nodeList.add(node); } publicvoiddisplay(){ System.out.println(name); for(inti=零;i<nodeList.size();i++){ nodeList.get(i).display(); } } } 該類從Node抽象類派生后,與原DirectNode類相比,主要有以下不同:①由定義兩個集合類成員變量轉(zhuǎn)為定義一個集合類成員變量nodeList;②由定義兩個添加方法轉(zhuǎn)為定義一個添加方法addNode();③display()方法,由兩個不同元素地循環(huán)轉(zhuǎn)為一個對相同質(zhì)節(jié)點Node地循環(huán)。也就是說,原DirectNode不論定義成員變量,成員方法,還是方法內(nèi)部地功能,都要實時考慮葉子節(jié)點,目錄節(jié)點地不同,因此它地各種定義一定是雙份地。而組合模式認為葉子節(jié)點,目錄節(jié)點是同一質(zhì)地節(jié)點,因此與原DirectNode類對比,它地各種定義工作一定是減半地,也易于擴充。四.一個簡單地測試類publicclassTest二{ publicstaticvoidcreateTree(Nodenode)throwsException{ Filef=newFile(); Filef二[]=f.listFiles(); for(inti=零;i<f二.length;i++){ if(f二[i].isFile()){ Nodenode二=newFileNode(f二[i].getAbsolutePath()); node.addNode(node二); } if(f二[i].isDirectory()){ Nodenode二=newDirectNode(f二[i].getAbsolutePath()); node.addNode(node二); createTree(node二); } } } publicstaticvoidmain(String[]args)throwsException{ Nodestart=newDirectNode("d://data"); createTree(start); start.display(); }}根據(jù)UML類圖,如圖一二-二所示。包括以下三種角色。 ?抽象節(jié)點:Node,是一個抽象類(或接口),定義了個體對象與組合對象需要實現(xiàn)地關(guān)于操作其子節(jié)點地方法,如add(),remove(),display()等。 ?葉結(jié)點:Leaf,從抽象節(jié)點Node派生,由于本身無后繼節(jié)點,其add()等方法利用Node抽象類相應(yīng)地默認實現(xiàn)即可,只需實現(xiàn)與自身有關(guān)地remove(),display()等方法即可。 ?組合結(jié)點:ponent,從抽象節(jié)點Node派生,包含其它posite節(jié)點或Leaf節(jié)點地引用。一九.三深入理解組合模式一九.三.一其它常用操作如:返回父節(jié)點,返回子女節(jié)點,返回兄弟節(jié)點。一.定義抽象節(jié)點NodeabstractclassNode{ protectedNodeparent=null; //定義父節(jié)點 publicvoidsetParent(Nodeparent){ this.parent=parent; } publicNodegetParent(){ returnparent; } publicNode[]getBrothers(){ //獲得兄弟節(jié)點 DirectNodeparent=(DirectNode)getParent(); if(parent==null) returnnull; intsize=parent.nodeList.size(); if(size==一) returnnull; Nodenodes[]=newNode[size-一]; for(inti=零;i<size;i++){ if(parent.nodeList.get(i)==this) continue; nodes[i]=parent.nodeList.get(i); } returnnodes; } publicabstractNode[]getChilds(); //其它所有代碼同一二.二代碼 }二.文件葉子節(jié)點類FileNodeclassFileNodeextendsNode{ //其它所有代碼同一二.二代碼 publicNode[]getChilds(){ returnnull; }}三.目錄節(jié)點類DirectNodeclassDirectNodeextendsNode{ //其它所有代碼同一二.二代碼 publicvoidaddNode(Nodenode)throwsException{ nodeList.add(node); node.setParent(this); //node地父節(jié)點是this節(jié)點 } publicNode[]getChilds(){ if(nodeList.size()==零) returnnull; Nodenodes[]=newNode[nodeList.size()]; for(inti=零;i<nodeList.size();i++){ nodes[i]=nodeList.get(i); } returnnodes; }}五.三.二節(jié)點排序我們知道有效樹形結(jié)構(gòu)數(shù)據(jù)比較方便查詢,那么什么是有效數(shù)據(jù)結(jié)構(gòu)呢?按每一層節(jié)點關(guān)鍵字排好序地樹就是一種有效地樹形數(shù)據(jù)結(jié)構(gòu)。例如英文字典樹,若第一層按"a,b,……,z"排好序,那么查"about"單詞只需按第一個分支"a"開始向下查,其它地分支根本勿需查。我們?nèi)砸砸欢?二目錄樹為例,按節(jié)點字符串名稱升序排列,其代碼如下所示。abstractclassNode{/*同一二.二*/}classFileNodeextendsNode{/*同一二.二*/}classDirectNodeextendsNode{ Set<Node>nodeList=newTreeSet(newparator(){ publicintpare(Objectobj,Objectobj二){ Nodeone=(Node)obj; Nodetwo=(Node)obj二; return.pareTo(); } }); publicDirectNode(Stringname){ super(name); } publicvoidaddNode(Nodenode)throwsException{ nodeList.add(node); } publicvoiddisplay(){ System.out.println(name); Iterator<Node>it=nodeList.iterator(); while(it.hasNext()){ Nodenode=it.next(); node.display(); } } }publicclassTest二{/*測試類同一二.二*/}一九.四應(yīng)用探究[例一]英漢字典查詢該字典樹地特點是:每層地節(jié)點值都是遞增地,子節(jié)點地值都大于等于父節(jié)點地值,但是小于父節(jié)點右側(cè)地最近地兄弟節(jié)點地值。例如,用表意形式講,[a,about][a],[a,about]<[b];另一個特點是所有英文單詞都是葉子節(jié)點,間節(jié)點都是分支節(jié)點。采用組合模式地具體代碼如下所示。一.單詞類WordclassWord{ Stringenglish; Stringchinese; publicWord(Stringenglish,Stringchinese){ this.english=english;this.chinese=chinese; }}二.組合模式抽象節(jié)點類NodeabstractclassNode{ Stringkey; //節(jié)點關(guān)鍵值 Wordw=null; Nodeparent=null;//父節(jié)點 publicNode(Stringkey,Wordw){ this.key=key; this.w=w; } publicNodegetParent(){ returnparent; } publicvoidsetParent(Nodeparent){ this.parent=parent; } publicvoidaddNode(Nodenode)throwsException{ thrownewException("Invalidexception"); } }三.單詞葉子節(jié)點類WordNodeclassWordNodeextendsNode{ publicWordNode(Stringenglish,Wordw){ super(english,w); }}四.間比較節(jié)點類MidNodeclassMidNodeextendsNode{ Set<Node>nodeList=newTreeSet(newparator(){ publicintpare(Objectobj,Objectobj二){ Nodeone=(Node)obj; Nodetwo=(Node)obj二; returnone.key.pareTo(two.key); } }); publicMidNode(Stringkey){ super(key,null); //Word對象設(shè)置為null } publicvoidaddNode(Nodenode)throwsException{ nodeList.add(node); node.setParent(this); } publicNodeget(intpos){//返回該節(jié)點地第pos個子節(jié)點,從零開始 Nodenode=null; Iterator<Node>it=nodeList.iterator(); for(inti=零;i<=pos;i++){ node=it.next(); } returnnode; }} 由于間節(jié)點只需要一個鍵值,勿需Word對象,因此在構(gòu)造方法利用"super(key,null)"將Word對象置為null即可。 到此為止,組合模式地功能類編制完畢了,應(yīng)用這些類如何編制英漢翻譯呢?筆者認為還要編制一個字典管理類Dictionary,里面至少要包含創(chuàng)建字典樹及查詢兩個方法,其代碼如下所示。classDictionary{ Noderoot=newMidNode("root"); publicvoidcreate()throwsException{/*代碼描述見下文*/} voidsearch(Stringenglish){/*代碼描述見下文*/} publicstaticvoidmain(String[]args)throwsException{ Dictionarydt=newDictionary(); dt.create(); dt.search("axis");dt.search("axis");dt.search("blind"); } } publicvoidcreate()throwsException{ Stringone[]={"a","b"}; Stringtwo[][]={{"a","ac","at"},{"b","bj","bt"}}; Stringthree[][][]={{{"a","about"},{"alike","amount"},{"awake","axis"}}, {{"baby","bike"},{"black","blind"},{"burn","but"}}}; Stringchina[][][]={{{"一個","關(guān)于"},{"象","數(shù)量"},{"醒","軸"}}, {{"嬰兒","自行車"},{"黑","瞎"},{"燃燒","但是"}}}; Nodeparent=null,parent二=null,child=null; for(inti=零;i<one.length;i++){ child=newMidNode(one[i]); root.addNode(child); //添加第一層子節(jié)點 } for(inti=零;i<one.length;i++){ parent=((MidNode)root).get(i);//獲得第一層結(jié)點 for(intj=零;j<two[i].length;j++){ child=newMidNode(two[i][j]); parent.addNode(child); //第一層節(jié)點添加第二層節(jié)點 } } for(inti=零;i<one.length;i++){ parent=((MidNode)root).get(i);//獲得第一層節(jié)點 for(intj=零;j<two[i].length;j++){ parent二=((MidNode)parent).get(j);//獲得第二層節(jié)點 for(intk=零;k<three[i][j].length;k++){ Wordw=newWord(three[i][j][k],china[i][j][k]); WordNodewn=newWordNode(three[i][j][k],w); parent二.addNode(wn); //添加第三層節(jié)點 } } } } voidsearch(Stringenglish){ Nodeparent=root; //從根節(jié)點向下開始查詢 Set<Node>s; Nodecur=null,next=null; Iterator<Node>it; while(true){ s=((MidNode)parent).nodeList; //獲得節(jié)點地子節(jié)點集合 it=s.iterator(); cur=it.next(); //設(shè)置當(dāng)前節(jié)點 while
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年石材供應(yīng)合同
- 2025工業(yè)區(qū)倉庫租賃合同模板
- 2025建筑工程包工不包料合同范本
- 2025年的單身公寓租賃合同樣本
- 2025年農(nóng)產(chǎn)品種子購銷合同
- 2025標準版簡單個人租房合同示例
- 2025年反擔(dān)保抵押合同范本
- 2025標準版城鎮(zhèn)公寓買賣合同
- 2025標準木材采購合同范本
- 《我國氣候特點》課件
- 2025年北京市三類人員安全員c3證考試題庫及答案
- 急性冠脈綜合征診斷及治療課件
- (四調(diào))武漢市2025屆高中畢業(yè)生四月調(diào)研考試 地理試卷(含答案)
- 吹小號的天鵝試題及答案
- 數(shù)據(jù)庫開發(fā) 試題及答案
- GB/T 45434.3-2025中國標準時間第3部分:公報
- 2024年鄭州工業(yè)應(yīng)用技術(shù)學(xué)院單招職業(yè)適應(yīng)性測試題庫附答案
- 農(nóng)業(yè)合作社管理與運營模式試題及答案
- Unit 4 Clothes 單元整體(教學(xué)設(shè)計)-2024-2025學(xué)年人教精通版(2024)英語三年級下冊
- 2025年版中等職業(yè)教育專業(yè)教學(xué)標準 710205 大數(shù)據(jù)技術(shù)應(yīng)用
- 2025年中國城市軌道交通維修行業(yè)投資潛力分析及行業(yè)發(fā)展趨勢報告
評論
0/150
提交評論