【Go-设计模式】组合模式 详解

shadowLogo

概念:

组合模式(Composite Pattern),又叫 部分整体模式
它创建了 对象组的树形结构,将 对象 组合成 树状结构 以表示 “整体-部分”的层次关系
这种类型的设计模式属于 结构型模式
组合模式使得用户对 单个对象组合对象 的访问 具有一致性
即:组合能让Client以 一致的方式 处理 个别对象 以及 组合对象

组合


UML:

uml

  • Component
    这是组合中对象声明接口,在适当情况下,实现 所有类共有的接口默认行为,用于 访问 和 管理
    Component 子部件, Component 可以是 抽象类 或者 接口
  • Leaf
    在组合中表示叶子节点,叶子节点没有子节点
  • Composite
    非叶子节点, 用于存储子部件, 在 Component 接口中实现 子部件的相关操作,比如增加(add), 删除。

示例:

组件接口:

type Component interface {
	Parent() Component
	SetParent(Component)
	Name() string
	SetName(string)
	AddChild(Component)
	Print(string)
}

const (
	LeafNode = iota
	CompositeNode
)

func NewComponent(kind int, name string) Component {
	var component Component
	switch kind {
	case LeafNode:
		component = NewLeaf()
	case CompositeNode:
		component = NewComposite()
	}

	component.SetName(name)
	return component
}

组件类:

type component struct {
	parent Component
	name   string
}

func (this *component) Parent() Component {
	return this.parent
}

func (this *component) SetParent(parent Component) {
	this.parent = parent
}

func (this *component) Name() string {
	return this.name
}

func (this *component) SetName(name string) {
	this.name = name
}

func (this *component) AddChild(Component) {}

func (this *component) Print(string) {}

普通节点组件:

type Composite struct {
	component
	childs []Component
}

func NewComposite() *Composite {
	return &Composite{
		childs: make([]Component, 0),
	}
}

func (this *Composite) AddChild(child Component) {
	child.SetParent(this)
	this.childs = append(this.childs, child)
}

func (this *Composite) Print(pre string) {
	fmt.Printf("%s+%s\n", pre, this.Name())
	pre += " "
	for _, comp := range this.childs {
		comp.Print(pre)
	}

叶子节点组件:

type Leaf struct {
	component
}

func NewLeaf() *Leaf {
	return &Leaf{}
}

func (this *Leaf) Print(pre string) {
	fmt.Printf("%s-%s\n", pre, this.Name())
}

测试:

package main

import (
	"DemoProject/design/base23/composite"	// 根据自己的项目路径定制
)

func main() {
	// composite
	root := composite.NewComponent(composite.CompositeNode, "root")
	c1 := composite.NewComponent(composite.CompositeNode, "c1")
	c2 := composite.NewComponent(composite.CompositeNode, "c2")
	c3 := composite.NewComponent(composite.CompositeNode, "c3")

	l1 := composite.NewComponent(composite.LeafNode, "l1")
	l2 := composite.NewComponent(composite.LeafNode, "l2")
	l3 := composite.NewComponent(composite.LeafNode, "l3")

	root.AddChild(c1)
	root.AddChild(c2)
	c1.AddChild(c3)
	c1.AddChild(l1)
	c2.AddChild(l2)
	c2.AddChild(l3)

	root.Print("")
}

后记:

为什么在本次示例中,本人要创建 一个组件接口,一个组件类 呢?
这是因为,模拟了 抽象类

因为在Golang中,类与类之间,即使拥有继承关系,也不能通过实例创建来互相引用
如下段代码:

type A struct {
	name string
	age  int
}

type B struct {
	// 实现结构
	A
	address string
}

cannot
我们可以看到:
显示不能使用 B类实例,来充当 A类对象

因此,上文中就通过 接口 + 类 的形式,来模拟 “抽象类
希望同学们能理解上文代码的细节

posted @ 2021-12-12 23:20  在下右转,有何贵干  阅读(159)  评论(0)    收藏  举报