设计模式——组合模式

2020-11-04  本文已影响0人  DevilRoshan

什么是组合模式?

将对象组合成树形结构以表示“部分-整体”的层次结构,用户对单个对象和组合对象的使用具有一致性。

实现

// 抽象公司
type Company interface {
    Add(company Company)
    Remove(company Company)
    Display(depth int)
    LineOfDuty()
}

// 具体公司
type ConcreteCompany struct {
    name         string
    companySlice []Company
}

func NewConcreteCompany(name string) *ConcreteCompany {
    return &ConcreteCompany{name: name}
}

func (this *ConcreteCompany) Add(company Company) {
    this.companySlice = append(this.companySlice, company)
}

func (this *ConcreteCompany) Remove(company Company) {
    for idx, comp := range this.companySlice {
        if comp == company {
            this.companySlice = append(this.companySlice[:idx], this.companySlice[idx+1:]...)
        }
    }
}

func (this *ConcreteCompany) Display(depth int) {
    for i := 0; i < depth; i++ {
        fmt.Print("-")
    }
    fmt.Println(this.name)
    for _, company := range this.companySlice {
        company.Display(depth + 1)
    }
}

func (this *ConcreteCompany) LineOfDuty() {
    for _, company := range this.companySlice {
        company.LineOfDuty()
    }
}

// 人力资源部
type HRDepartment struct {
    name         string
    companySlice []Company
}

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

func (this *HRDepartment) Add(company Company) {
}

func (this *HRDepartment) Remove(company Company) {
}

func (this *HRDepartment) Display(depth int) {
    for i := 0; i < depth; i++ {
        fmt.Print("-")
    }
    fmt.Println(this.name)
}

func (this *HRDepartment) LineOfDuty() {
    fmt.Println("员工招聘培训管理: ", this.name)
}

// 财务部
type FinanceDepartment struct {
    name         string
    companySlice []Company
}

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

func (this *FinanceDepartment) Add(company Company) {
}

func (this *FinanceDepartment) Remove(company Company) {
}

func (this *FinanceDepartment) Display(depth int) {
    for i := 0; i < depth; i++ {
        fmt.Print("-")
    }
    fmt.Println(this.name)
}

func (this *FinanceDepartment) LineOfDuty() {
    fmt.Println("公司财务收支管理: ", this.name)
}

func TestNewConcreteCompany(t *testing.T) {
    // 总公司
    root := NewConcreteCompany("东莞总公司")
    root.Add(NewFinanceDepartment("总公司财务部"))
    root.Add(NewHRDepartment("总公司人力资源部"))
    // 上海分公司
    companySH := NewConcreteCompany("上海分公司")
    companySH.Add(NewFinanceDepartment("上海公司财务部"))
    companySH.Add(NewHRDepartment("上海公司人力资源部"))
    root.Add(companySH)
    // 南京分公司
    companyNJ := NewConcreteCompany("南京分公司")
    companyNJ.Add(NewFinanceDepartment("南京公司财务部"))
    companyNJ.Add(NewHRDepartment("南京公司人力资源部"))
    root.Add(companyNJ)
    // 深圳分公司
    companySZ := NewConcreteCompany("深圳分公司")
    companySZ.Add(NewFinanceDepartment("深圳公司财务部"))
    companySZ.Add(NewHRDepartment("深圳公司人力资源部"))
    root.Add(companySZ)
    // 取消上海分公司
    root.Remove(companySH)

    fmt.Println("结构图")
    root.Display(1)

    fmt.Println("职责")
    root.LineOfDuty()
}
// === RUN   TestNewConcreteCompany
// 结构图
// -东莞总公司
// --总公司财务部
// --总公司人力资源部
// --南京分公司
// ---南京公司财务部
// ---南京公司人力资源部
// --深圳分公司
// ---深圳公司财务部
// ---深圳公司人力资源部
// 职责
// 公司财务收支管理:  总公司财务部
// 员工招聘培训管理:  总公司人力资源部
// 公司财务收支管理:  南京公司财务部
// 员工招聘培训管理:  南京公司人力资源部
// 公司财务收支管理:  深圳公司财务部
// 员工招聘培训管理:  深圳公司人力资源部
// /--- PASS: TestNewConcreteCompany (0.00s)
// PASS

优点

缺点

使用场景

上一篇下一篇

猜你喜欢

热点阅读