iT邦幫忙

2023 iThome 鐵人賽

DAY 1
0
自我挑戰組

掘地土撥鼠的設計歷險記系列 第 9

 Composite Pattern - 組合模式

  • 分享至 

  • xImage
  •  

Hi all 綜合到上一篇為止,我們在創建型的設計模型的實作學習就到這了。
在接下來的篇章中我們會開始著手在結構型的設計模型,說來說去那就從這一篇開始。

Introduction

中文為組合模式 (Composite Pattern),是一種將一組物件當作單一物件使用的模式。組合模式讓開發者有個樹狀結構的物件關係,並可要求每個節點執行任意任務,其主要功能是在整個樹狀結構使用遞迴方法並將結果進行整合。

組合模式中的角色有

  • 組件 (Component)
  • 子節點 (Leaf): 組合模式中的最小單位,每個節點中可以被賦予任務,繼承組件
  • 組合 (Composite): 多個子節點組成的集合,其任務是將底下所有的子節點任務執行過一輪,繼承組件
    使用端 (main)

使用場景

  • 當使用端需要忽略組合和單一物件的差異時,即可使用組合模式。
  • 若使用端需要依序處理大量同個類別的多個物件,即可使用組合模式。
  • 需要實現樹狀結構時,即可使用組合模式。在此模式中新增/刪除節點都非常方便,並可依循封閉開放原則。

雛形演練

在此雛形我們將嘗試透過組合模型拉出個樹狀節點,如圖
https://ithelp.ithome.com.tw/upload/images/20230906/20115082MUFMTEtg5P.png

UML

https://ithelp.ithome.com.tw/upload/images/20230906/20115082WMi9L5pI0Y.jpg

Component

package Components

type Component interface {
	Excute()
	Add(Component)
}

Leaf

package Leaves

import (
	components "composit-pattern/Components"
	"fmt"
)

type Leaf struct {
	value int
}

func NewLeaf(value int) *Leaf {
	return &Leaf{value: value}
}

func (l *Leaf) Excute() {
	fmt.Println(l.value)
}

func (l *Leaf) Add(c components.Component) {
}

Composite

package composites

import (
	components "composit-pattern/Components"
)

type Composite struct {
	children []components.Component
}

func NewComposite() *Composite {
	// TODO: return  a zero-length composite
	return &Composite{make([]components.Component, 0)}
}

func (c *Composite) Add(component components.Component) {
	c.children = append(c.children, component)
}

func (c *Composite) Excute() {
	for i := 0; i < len(c.children); i++ {
		c.children[i].Excute()
	}
}

Main

package main

import (
	composites "composit-pattern/Composites"
	leaves "composit-pattern/Leaves"
)

func main() {

	composit := composites.NewComposite()
	leaf1 := leaves.NewLeaf(1)
	composit.Add(leaf1)

	leaf2 := leaves.NewLeaf(2000)
	composit.Add(leaf2)

	composit2 := composites.NewComposite()
	composit.Add(composit2)

	leaf3 := leaves.NewLeaf(3)
	composit2.Add(leaf3)

	composit.Excute()
}

優缺點分析

優點

  • 開發人員無需了解樹狀結構的物件如何實現,也不需了解子節點是複雜或是簡單的物件,只需要使用介面中定義的方法,並以相同的方式去做處理即可。
  • 使用端可以把物件集合跟單一物件交互使用。
  • 如果使用的是基本節點則直接處理,若為集合則轉發給底下的節點進行處理。

缺點

  • 在特定的情況下,很難將組件限定為特定的類別。為了達成此種約束,運行時就必須依賴於事前的檢查,因為組合模式無法固定讓特定的類別進行實作。
  • 一旦定義了樹狀結構,組合模式就會只其更加籠統。

Conclusion

Code

在程式方面,我們在NewComposite()中學到透過make 建立一個新陣列且給予其初始值。
此外也透過前篇文章中學到的**append()**為我們的陣列新增成員。

Design pattern

通過本篇的學習,我們可以理解到組合模式不僅可以簡化客戶端的程式碼,更可以使系統更加靈活和可擴展。它將「整體」和「部分」的操作統一,並可以輕鬆地添加或移除組件。 然而,正如我們所討論的,它也有其缺點,特別是在試圖限制組件類別時可能會遇到困難。但是,正確應用時,它可以大大提升系統的模塊化和可維護性。


上一篇
Object Pool - 物件池模式
下一篇
[補] Object Pool 實際應用
系列文
掘地土撥鼠的設計歷險記11
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言