Composite 組合模式:

將物件組織成樹狀結構, 部分-全體 層級關係, 讓外界以一致性的方式對待個別物件和整體物件

將物件組合成樹形結構以表示 部分-整體的層次結構. 組合模式使得用戶對單個物件和組合物件的使用具有一致性

  • 何時使用組合模式 需求中是表現部分與整體曾是的結構時, 以及你希望用戶可以忽略組合物件與單個物件的不同, 統一地使用組合結構中的所有物件時, 就應該考慮組合模式.

UML

Example

https://github.com/kimi0230/DesignPatternGolang/tree/master/Composite

package composite

import (
    "fmt"
    "strings"
)

// Company : Component
type Company interface {
    Add(Company)
    Remove(Company)
    Display(int)
    LineOfDuty()
}

type RealCompany struct {
    name string
}

// ConcreteCompany : Composite
type ConcreteCompany struct {
    RealCompany
    children []Company
}

func NewConcreteCompany(name string) *ConcreteCompany {
    return &ConcreteCompany{RealCompany{name}, []Company{}}
}

func (c *ConcreteCompany) Add(com Company) {
    if c == nil {
        return
    }
    c.children = append(c.children, com)
}

func (c *ConcreteCompany) Remove(com Company) {
    if c == nil {
        return
    }
    for i, v := range c.children {
        if v == com {
            c.children = append(c.children[:i], c.children[i+1:]...)
            return
        }
    }
    return
}

func (c *ConcreteCompany) Display(depth int) {
    if c == nil {
        return
    }
    fmt.Println(strings.Repeat("  ", depth-1), "|--", c.name)
    for _, v := range c.children {
        v.Display(depth + 2)
    }
}

func (c *ConcreteCompany) LineOfDuty() {
    if c == nil {
        return
    }
    for _, v := range c.children {
        v.LineOfDuty()
    }
}

// HR
type HRDepartment struct {
    RealCompany
}

func NewHRDepartment(name string) *HRDepartment {
    return &HRDepartment{RealCompany{name}}
}

func (h *HRDepartment) Add(c Company)    {}
func (h *HRDepartment) Remove(c Company) {}
func (h *HRDepartment) Display(depth int) {
    if h == nil {
        return
    }
    fmt.Println(strings.Repeat("  ", depth-1), "|--", h.name)
}

func (h *HRDepartment) LineOfDuty() {
    if h == nil {
        return
    }
    fmt.Println(h.name, "員工招聘教育訓練管理")
}

// 財務部
type FinanceDepartment struct {
    RealCompany
}

func NewFinanceDepartment(name string) *FinanceDepartment {
    return &FinanceDepartment{RealCompany{name}}
}

func (f *FinanceDepartment) Add(c Company)    {}
func (f *FinanceDepartment) Remove(c Company) {}
func (f *FinanceDepartment) Display(depth int) {
    if f == nil {
        return
    }
    fmt.Println(strings.Repeat("  ", depth-1), "|--", f.name)
}

func (f *FinanceDepartment) LineOfDuty() {
    if f == nil {
        return
    }
    fmt.Println(f.name, "公司財務收支管理")
}
© Kimi Tsai all right reserved.            Updated : 2022-09-30 06:29:46

results matching ""

    No results matching ""