Typescript 組合模式(Composite)


請仔細閱讀下面代碼,理解其中的設計理念。

 
composite.jpg

組合模式

組合模式: 將對象組合成樹形結構以表示“部分整體”的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。

實際場景

為了方便我們對多個文件的管理,我們引入了“文件夾-文件”的模式。將具有統一性質的文件放入一個文件夾中,將具有統一性質的文件夾再放入另一個文件夾中。可以對整個文件夾系統進行文件的搜索,也可以對某一個文件夾進行搜索。讓文件管理變得簡單。
而“文件夾-文件”這種結構就是典型 的組合模式。

組合模式的結構

  • Component 是組合中的對象聲明接口,在適當的情況下,實現所有類共有接口的默認行為。聲明一個接口用於訪問和管理Component子部件。
  • Leaf 在組合中表示葉子結點對象,葉子結點沒有子結點。
  • Composite 定義有枝節點行為,用來存儲子部件,在Component接口中實現與子部件有關操作,如增加(add)和刪除(remove)等。

組合模式的例子

現在要實現一個文件夾文件樹

Node枚舉

/* node-type-enum.ts */ enum NodeTypeEnum { ImageFile = 'image', TextFile = 'text', Folder = 'folder', } export { NodeTypeEnum } 

Node抽象類

/* abstract-node.ts */ import { NodeTypeEnum } from './node-type-enum'; export abstract class AbstractNode { protected name: string; protected type: NodeTypeEnum; protected children: AbstractNode[]; public abstract add(node: AbstractNode): AbstractNode; public abstract getFileDeep(name: string): AbstractNode; } 

文件和文件夾基礎類

/* basic-file-folder.ts */ import { AbstractNode } from './abstract-node'; import { NodeTypeEnum } from './node-type-enum'; export abstract class BasicFile extends AbstractNode { public add (file: BasicFile): BasicFile { console.error('文件類型不支持添加'); return this; } public getFileDeep (name: string): BasicFile { if (name === this.name) { return this; } return null; } } export abstract class BasicFolder extends AbstractNode { protected constructor () { super(); this.type = NodeTypeEnum.Folder; this.children = []; } public add (file: AbstractNode): BasicFolder { this.children.push(file); return this; } public getFileDeep (name: string): AbstractNode { if (this.name === name) { return this; } for (let index = 0; index < this.children.length; index++) { const node = this.children[index].getFileDeep(name); if (node) { return node; } } return null; } } 

文件類

/* files.ts */ import { BasicFile } from './basic-file-folder'; import { NodeTypeEnum } from './node-type-enum'; export class ImageFile extends BasicFile { constructor (name: string) { super(); this.name = name; this.type = NodeTypeEnum.ImageFile; } } export class TextFile extends BasicFile { constructor (name: string) { super(); this.name = name; this.type = NodeTypeEnum.TextFile; } } 

文件夾類

/* folder.ts */ import { BasicFolder } from './basic-file-folder'; export default class SystemFolder extends BasicFolder{ constructor(name){ super(); this.name = name; } } 

客戶端

/* client.ts */ import { ImageFile, TextFile } from './files'; import SystemFolder from './folder'; export default class Client { public static initTree (): SystemFolder { const folder1: SystemFolder = new SystemFolder('根文件夾'); const folder2: SystemFolder = new SystemFolder('圖像文件夾'); const folder3: SystemFolder = new SystemFolder('文本文件夾'); const image1: ImageFile = new ImageFile('a.jpg'); const image2: ImageFile = new ImageFile('b.jpg'); const text1: TextFile = new TextFile('a.txt'); const text2: TextFile = new TextFile('b.txt'); folder2.add(image1).add(image2); folder3.add(text1).add(text2); folder1.add(folder2).add(folder3); return folder1; } } const tree = Client.initTree(); const aJpg = tree.getFileDeep('a.jpg'); console.log(aJpg); 

組合模式的利弊

利:

  • 減少大量手工遍歷數組或其他數據的粘合性代碼
  • 組合模式中各個對象耦合非常松散,更容易改變他們或互換位置,有利於代碼重構
  • 讓代碼有一個出色的層次體系,客戶端調用更方便

弊:
組合模式掩蓋了他所支持的每一種操作的代價。如果層次體系很大的話,系統的性能將會收到影響。



作者:我不叫奇奇
鏈接:https://www.jianshu.com/p/1f8c6ebaf6b6
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM