美文网首页
go面向对象和设计模式

go面向对象和设计模式

作者: mafa1993 | 来源:发表于2023-03-17 08:58 被阅读0次
    1. go没有类型继承
    2. go的继承不存在is-a关系
    type parent struct {
        a int
    }
    type sub struct {
        p parent
        a int
    }
    
    func NewPeople(p *parent) *parent{
        return &p;
    }
    
    func (p *parent)dump(){
        fmt.Printf("p %s",p.a)
    }
    
    func(s *sub)dump(){
        fmt.Printf("s %s",s.p.a)
    }
    
    func main(){
        
        a := NewPeople(&people{a:1})
    
        // b := NewPeople(&sub{p:p,a:2})  // 会报错,
    
        b:= sub{parent{a:1},a:2}
        b.dump()  // 打印不出父类的a值
    }
    

    interface的特点

    1. 不需要显示声明关系,只要两者方法集有包含关系,则看做同一类型

    solid原则

    1. SRP 单一职责, 一个模块只有一个功能,一个文件也要只有一个功能
    2. OCP 开闭原则,软件实体(类、模块、函数)应该是可扩展的,但不可修改,对扩展是开放的,对修改是关闭的
    3. 里氏替换原则LSP,可以用子类替换父类,实现interface和function type时,不能破坏其对外的契约,要做到宽进严出,即:入参宽泛,出参严格控制,子类的校验要比父类更宽泛
    4. ISP 接口隔离原则,功能相互隔离
    5. DIP 依赖倒置原则,高层不应该依赖底层,底层应该依赖于接口,例如A要依赖B,可以把A的依赖改成一个接口,B去实现这个接口

    常用设计模式

    1. 工厂方法,创建相关对象的时候,根据传参决定创建哪个对象
    package main 
    import "fmt"
    
    type cni interface {
        createNet()
    }
    
    type canai struct {}
    func(c canai) createNet(){
        fmt.Println("c create net")
    }
    
    type calico struct{}
    func(c calico) createNet(){
        fmt.Println("ca create")
    }
    
    func cniFactory(name string)cni {
        switch name {
            case "canai":
                return canai{};
            case "calico":
                return calico{}
        }
    }
    
    
    func main() {
        canai := cniFactory("canai")
        canai.createNet()
    
        calico := cniFactory("calico")
        calico.createNet()
    
    }
    
    1. 抽象工厂,创建一组对象
    2. 生成器
    package main 
    import "fmt"
    
    type req interface{
        send()
    }
    
    type cniReq struct {
        network string 
        qos interface{}
        multiIP bool
        fixIP bool
    }
    
    func (c *cniReq) send(){
        fmt.Println("send req ")
    }
    
    // 用于生成builder
    type cniReqBuilder interface {
        withNetwork(network string)cniReqBuilder
        withQos(qos interfacd) cniReqBuilder
        withMultiIP() cniReqBuilder
        withFixIP() cniReqBuilder
        build() req  // 用于生成req
    }
    
    type builder struct {
        network string 
        qos interface{}
        multiIP bool
        fixIP bool
    }
    
    // 用于builder对象属性的设置
    func (b *builder)withNerwork(network string) cniReqBuilder{
        b.network=network
        return b
    }
    func (b *builder)withQos(network interface{}) cniReqBuilder{
        b.network=network
        return b
    }
    
    func (b *builder)withMultiIP() cniReqBuilder{
        return b
    }
    func (b *builder)withFixIP() cniReqBuilder{
        return b
    }
    
    func(b *builder) build() req {
        return &cniReq{
            network:b.network,
            qos:b.qos,
            multiIP:b.multiIP,
            fixIP:b.fixIP,
        }
    }
    
    func NewBuilder() cniReqBuilder {
        return builder{}
    }
    
    func main() {
        // 利用builder创建req
        cniReq := NewBuilder().withNetWork("x").
        withQos(nil).
        withFixIP().
        build()
        cni.send();
    }
    
    1. 原型
    package main
    import "fmt"
    type machineTemp struct {
        name string 
        disk int
        network string
        os string
        runtime string
    }
    
    func (m *machineTemp) deepCopy() *machineTemp{
        return &machineTemp{
            name: m.name,
            disk:m.disk,
            network:m.network,
            os:m.os,
            runtime:m.runtime
        }
    }
    
    // 从数据库等获取一个模板,模板不能进行修改,所以开始要deepcopy,然后修改copy的对象
    func getMachineTemp()*matchineTemp{
        template := getMachineTemp()
    
        t := template.deepCopy()
    
        t.os = "xx"
        
    }
    
    1. 单例模式,创建的对象比较大,又经常使用
    package main
    import (
        "fmt"
        "sync"
    )
    
    var (
        globalConf * conf
        once = &sync.Once{}
    )
    
    type conf struct {
        ip string
        port int
    }
    
    func (c config)getIP() string{
        return c.ip
    }
    
    func getInstance() *config {
        once.Do(func(){
            // 这里可能需要解析配置文件,会比较耗费资源,使用单例,只执行一次
            globalConf = &conf{
                ip:"x",
                port:1
            }
        })
        return globalConf
    }
    
    func main(){
        ip:=getInstance().getIP()
        port := getInstance().port
    }
    

    相关文章

      网友评论

          本文标题:go面向对象和设计模式

          本文链接:https://www.haomeiwen.com/subject/zwcjrdtx.html