• Go!Go!Go!设计模式-组合设计模式


    零:前言

    参考链接:https://github.com/senghoo/golang-design-pattern/blob/master/13_composite/composite.go
    组合模式统一对象和对象集,使得使用相同接口使用对象和对象集。
    组合模式常用于树状结构,用于统一叶子节点和树节点的访问,并且可以用于应用某一操作到所有子节点。



    核心思想:
    的当整体的架构是一个树状:有树根,树枝,树叶三部分组成,而他们相互之间有着共同的从属关系,
    即树根 包含多个树枝,每个树枝上有多个树叶,整体是一个"发散"的形态,
    其中,树根 和 树枝都是有下级的,即需要包含另一部分,所以认为是"集成部件",
    树叶没有下级,是一个"原子部件"
    那么,就可以使用组合模式,将整个的行为关系抽象到一个接口上,然后不同的部件对应去实现


    具体的实现步骤为:
    1.定义"从属关系"的接口;
    2.定义"从属关系"的结构体,实现对应的接口。其中完全可以复用的方法直接实现,需要定制化的则可以是虚方法的方式呈现;
    3.根据在整个逻辑中的不同"定位"分别实现这种从属关系接口,在这里通过内嵌结构体的方式直接继承公共方法,然后分别实现特有方法;
    4.实例化各个部位,然后利用关系函数(即"从属关系"中的方法)来和自己的"下属"或"上级"建立关系。

    二. 样例
    //1. 定义"关联性"接口,规划了从属关系的整体形态
    type Relevance interface {
        Parent() Relevance
        SetParent(Relevance)
        Name() string
        SetName(string)
        AddChild(Relevance)
        Print(string)
    }
    
    const (
        atomNode = iota   //"原子部件类型"
        compositeNode      //"集成部件类型"
    )
    
    //2.定义"相关性"结构体, 除了实现"相关性"的接口外, 还具备两个元素:自己的名字 和 自己的上级
    type relevance struct {
        parent Relevance
        name   string
    }
    func (c *relevance) Parent() Relevance {
        return c.parent
    }
    func (c *relevance) SetParent(parent Relevance) {
        c.parent = parent
    }
    func (c *relevance) Name() string {
        return c.name
    }
    func (c *relevance) SetName(name string) {
        c.name = name
    }
    //特色方法,待实现
    func (c *relevance) AddChild(Relevance) {}
    func (c *relevance) Print(string) {}
    
    func NewComponent(kind int, name string) Relevance {
        var c Relevance
        switch kind {
        case atomNode:
            c = NewLeaf()
        case compositeNode:
            c = NewComposite()
        }
    
        c.SetName(name)
        return c
    }
    
    //3.具象化1: 原子部件类型的"叶子"结构体,  内嵌一个"关系"结构体
    type Leaf struct {
        relevance
    }
    //其中,Print方法有override
    func (c *Leaf) Print(pre string) {
        fmt.Printf("%s-%s
    ", pre, c.Name())
    }
    
    
    func NewLeaf() *Leaf {
        return &Leaf{}
    }
    
    
    
    //3. 具象化2: 集成部件类型的"集成"结构体:  自身的"关系网"  + 子部件的"关系网"
    //   重写AddChild方法和Print方法
    type Composite struct {
        relevance
        childs []Relevance   //树枝  or  叶子
    }
    func (c *Composite) AddChild(child Relevance) {
        child.SetParent(c)
        c.childs = append(c.childs, child)
    }
    func (c *Composite) Print(pre string) {
        fmt.Printf("%s+%s
    ", pre, c.Name())
        pre += " "
        for _, comp := range c.childs {
            comp.Print(pre)
        }
    }
    
    func NewComposite() *Composite {
        return &Composite{
            childs: make([]Relevance, 0),
        }
    }

    测试逻辑如下:
    //1.创建四个"集成部件",一个作为根, 其余作为树枝
    root := NewComponent(compositeNode, "root")
    branch1 := NewComponent(compositeNode, "branch1")
    branch2 := NewComponent(compositeNode, "branch2")
    branch3 := NewComponent(compositeNode, "branch3")
    
    //2.创建3个"原子部件",均作为叶子
    leaf1 := NewComponent(atomNode, "leaf1")
    leaf2 := NewComponent(atomNode, "leaf2")
    leaf3 := NewComponent(atomNode, "leaf3")
    
    //3.为1个根添加2个树枝,为其中给1个树枝再添加1个树枝,为其中2个树枝分别添加1个和2个叶子
    root.AddChild(branch1)
    root.AddChild(branch2)
    branch1.AddChild(branch3)
    
    branch1.AddChild(leaf1)
    branch2.AddChild(leaf2)
    branch2.AddChild(leaf3)
    
    root.Print("")
    
    结果:
    +root
     +branch1
      +branch3
      -leaf1
     +branch2
      -leaf2
      -leaf3
    
    
    三.小小结
    component: 成分; 部件; 组成部分;
    composite: 复合材料; 合成物; 混合物;
    这种模式一般用来规范行为的,即对于一些有从属关系树状逻辑,这种所谓的"从属关系"就可以抽象出来了
  • 相关阅读:
    js调用手机震动
    模拟器 Android Studio
    不修改代码,让调用方法 替换到另外一个方法
    springboot 获取请求 / 响应 接收和设置请求头 、请求码的方法
    mysql binlog 实现数据库同步先占位 有空研究下
    Airtest无线连接android手机
    springboot + spring cloudeureka
    更新一条数据多个字段的方法
    PyAutoGUI 操作C端 识别图片 点击(有空就看一下) 可以替代 Autoit
    playwright入门
  • 原文地址:https://www.cnblogs.com/shuiguizi/p/14235389.html
Copyright © 2020-2023  润新知