iT邦幫忙

2022 iThome 鐵人賽

DAY 25
0

結構型模式之組合模式

受到React Hook啟發,Vue推出了Composition API,
從來沒想過[Composition]組合是什麼意思嗎?

今天就來看看一起看看這個"Composition Pattern"。

延伸閱讀:
Comparing React Hooks with Vue Composition API

** 使用情境 **

  1. 當你要處理一個樹狀結構的物件時(或有階層關係)

組合模式要處理的情境主要為樹狀結構,
譬如說一個公司組織的階層、電腦裡面資料夾的目錄
組合模式為"結構型模式"的大分類。

主要應用到的重要詞彙:

  • Leaf 樹葉:一個可以存在在結構裡或結構外的物件
  • Composite : 多個leaves(樹葉)的組合,可以是leaf和其他composite
  • Component Interface:樹葉和composite 擴充的介面

TS 案例

這邊以資料夾的樹狀結構來看看組合模式。
可以來TS Playground試試看

// 1.我們的資料和資料夾會擴充的原型
interface MyComponent {
    myParentFolder?: Folder

    printDir(indent: string): void
    // 每個葉節點和Composite組合都要有的函式

    detach(): void
    // 將移除葉節點從現在的資料夾移開
}

// 2.我們的資料類別,這就是樹葉節點
class MyFile implements MyComponent {
    name: string
    myParentFolder?: Folder = undefined

    constructor(name: string) {
        this.name = name
    }

    printDir(indent: string): void {
        console.log(`${indent}<檔案> ${this.name}`)
    }

    //注意這邊從現在的資料夾斷開關係時,是呼叫資料夾類的函式
    detach(): void {
        if (this.myParentFolder) {
            this.myParentFolder.delete(this)
        }
    }
}

//3.我們的資料夾Composite,可以包含我們的葉節點或另一個Composite
class Folder implements MyComponent {

    myParentFolder?: Folder
    name: string
    myChildrenFiles: MyComponent[]

    constructor(name: string) {
        this.name = name
        this.myChildrenFiles = []
    }

    printDir(indent: string): void {
        console.log(`${indent}<資料夾>  ${this.name}`)

        //資料夾裡的資料夾裡的檔案就會多3個...
        this.myChildrenFiles.forEach((myChildrenFiles) => {
            myChildrenFiles.printDir(indent + '...')
        })
    }

    attach(component: MyComponent): void {
        // 先將目標資料從他本來的目錄移除,再移動到新資料夾
        component.detach()
        component.myParentFolder = this
        this.myChildrenFiles.push(component)
    }

    delete(component: MyComponent): void {
        // 把傳入的檔案從自己身上移除
        const index = this.myChildrenFiles.indexOf(component)
        if (index > -1) {
            this.myChildrenFiles.splice(index, 1)
        }
    }

    detach(): void {
        // 如果資料夾上面還有資料夾的話,斷開關係
        if (this.myParentFolder) {
            this.myParentFolder.delete(this)
            this.myParentFolder = undefined
        }
    }
}

//4. 創建資料夾囉
const FILESYSTEM = new Folder('1.African Countries')
const FILE_1 = new MyFile('Nigeria.txt')
const FILE_2 = new MyFile('Ghana.txt')
FILESYSTEM.attach(FILE_1)
FILESYSTEM.attach(FILE_2)

const FOLDER_A = new Folder('East Africa')
FILESYSTEM.attach(FOLDER_A)
const FILE_3 = new MyFile('Kenya.txt')
FOLDER_A.attach(FILE_3)

const FOLDER_B = new Folder('Southern Africa')
const FILE_4 = new MyFile('South Africa.txt')
FOLDER_B.attach(FILE_4)
FILESYSTEM.attach(FOLDER_B)
FILESYSTEM.printDir('')

// now move FOLDER_A and its contents to FOLDER_B
console.log('-----------------分隔線------------------')
FOLDER_B.attach(FOLDER_A)
FILESYSTEM.printDir('')

印出來的結果:

[LOG]: "<資料夾>  1.African Countries" 
[LOG]: "...<檔案> Nigeria.txt" 
[LOG]: "...<檔案> Ghana.txt" 
[LOG]: "...<資料夾>  East Africa" 
[LOG]: "......<檔案> Kenya.txt" 
[LOG]: "...<資料夾>  Southern Africa" 
[LOG]: "......<檔案> South Africa.txt" 
[LOG]: "-----------------分隔線------------------" 
[LOG]: "<資料夾>  1.African Countries" 
[LOG]: "...<檔案> Nigeria.txt" 
[LOG]: "...<檔案> Ghana.txt" 
[LOG]: "...<資料夾>  Southern Africa" 
[LOG]: "......<檔案> South Africa.txt" 
[LOG]: "......<資料夾>  East Africa" 
[LOG]: ".........<檔案> Kenya.txt" 

改寫引用自:Composite Design Pattern

應用到的原則

  1. 開關原則 Open-Close principle (OCP)
    1. 添加新的物件,也不會影響原有的程式碼
  2. 依賴反轉原則 Dependency inversion principle (DIP)
    1. 我們的Composite複合類型不依賴任何具體組件,只依賴抽象

以上!

這幾天,我們用TS看了設計模式三大分類,

回頭來看一下菜鳥初探設計模式-D21提到的三大分類,好像有比較理解了!

A. 創建型模式( Creational Patterns)
主要在於"創造對象",將創造與使用分開,並能增進程式碼靈活度,以及重複利用程式碼。
工廠模式--D22
抽象工廠模式-D23

B.結構型模式(Structural Patterns)
將類和物件組成更大的結構,並同時保持彈性。
今天的組合模式。

C.行為型模式(Behavioral Patterns) 用來識別對象間的交流模式,並分配職責。
觀察者模式-D24

不過我的設計模式之旅先在此畫上一個逗號啦,
剩下的鐵人,繼續把其他菜鳥想要了解的東西搞個清楚囉。



環遊非洲第25天-渡假勝地模里西斯

連續兩天又來推坑大家去旅遊啦!
位在非洲最東邊的國家模里西斯擁有美麗的海景,常常是全球度假、蜜月勝地榜上的常勝軍。
也是陳小春和應采兒的結婚地方。

2020年模里西斯的人均GDP為8,892美元,比泰國、阿根廷排名高,是非洲第2高,世界銀行更將毛里求斯列為「高收入」國家。原因之一是因為他們的低稅收,吸引外資進入,重要產業如旅遊服務業、銀行業、紡織業。
另外她還是個[沒有官方語言]的國家!
模里西斯因為位於非洲最東方,和印度相近,也是非洲最靠近亞洲的地方,國內有很多印度裔,以及殖民時代的英國、法國各種移民。或許是因為這樣的原因,模里西斯沒有設立官方語言,但是政府單位還是都採用英語文書,並可以法語溝通,但最多人可以說的語言還是:模里西斯克里奧爾語(Mauritian Creole)

https://ithelp.ithome.com.tw/upload/images/20221010/20140247eyOwh8gqL9.jpg

https://ithelp.ithome.com.tw/upload/images/20221010/20140247mVz1Xh6QQz.jpg
圖片來源
圖片來源


參考

Composite Design Pattern


上一篇
觀察者模式-用TS挑戰設計模式-D24
下一篇
把專案Nuxt3起來&config設定-D26
系列文
分手前端菜雞之旅@非洲30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言