今天我想聊聊Golang语言下的设计模式问题,我觉得这个话题还是比较有意思的。用Go把设计模式实现一遍。构建一个知识库。 虽然网上有《Go Patterns》,不过是英文版的,并且不全,我就想把它翻译成中文的,并且补全。

单利设计模式(Singleton)

单例对象的类必须保证只有一个实例存在,全局有唯一接口访问

实现

type singleton map[string]interface{}

var once sync.Once
var instance singleton

func New() singleton {
    once.Do(func() {
        instance = make(singleton)
    })
    return instance
}

func (s singleton) GetInstance() singleton {
    return New()
}

测试

测试单利模式的实现

func main() {
    singletons := instance.GetInstance()
    singletons["this"] = "that"

    getInstance := instance.GetInstance()
    value := getInstance["this"]
    fmt.Println(`singletons["this"] = `, value)
}

结果

singletons["this"] =  that

工厂设计模式

工厂根据条件产生不同功能的类。工厂模式使用经常使用在替代new的场景中,让工厂统一根据不同条件生产不同的类。工厂模式在解耦方面将使用者和产品之间的依赖推给了工厂,让工厂承担这种依赖关系。工厂模式又分为简单工厂,抽象工厂。

实现

import "fmt"

type TeaFactory interface {
    CreateTea() Tea
}

type BlackTeaFactory struct {
}

func (b BlackTeaFactory) CreateTea() Tea {
    return BlackTea{}
}

type GreenTeaFactory struct {
}

func (g GreenTeaFactory) CreateTea() Tea {
    return GreenTea{}
}

type Tea interface {
    Drinking()
}

type BlackTea struct {
}

func (b BlackTea) Drinking() {
    fmt.Println("Drinking BlackTea")
}

type GreenTea struct {
}

func (g GreenTea) Drinking() {
    fmt.Println("Drinking GreenTea")
}

测试

测试工厂模式的实现

func main() {
    gtf := GreenTeaFactory{}
    gtf.CreateTea().Drinking()

    btf := BlackTeaFactory{}
    btf.CreateTea().Drinking()
}

结果

Drinking GreenTea
Drinking BlackTea

观察者设计模式

观察者模式使得一种类型的实例可以发送事件给其他类型,前提是接收事件的实例要根发送者订阅这个事件。

实现

import "fmt"

type (
    Event struct {
        Msg string
    }

    Observer interface {
        OnNotify(Event)
    }

    Notifier interface {
        Register(Observer)

        UnRegister(Observer)

        Notify(Event)
    }

    EventCenter struct {
        observers []Observer
    }

    EventReceiver struct {
    }
)

func (e *EventCenter) Register(observer Observer) {
    e.observers = append(e.observers, observer)
}

func (e *EventCenter) UnRegister(observer Observer) {
    for i, o := range e.observers {
        if o == observer {
            e.observers = append(e.observers[:i], e.observers[i+1:]...)
            break
        }
    }
}

func (e *EventCenter) Notify(event Event) {
    for _, o := range e.observers {
        o.OnNotify(event)
    }
}

func (e EventReceiver) OnNotify(event Event) {
    fmt.Printf("Receiver receive: %s\n", event.Msg)
}

func NewEventCenter() *EventCenter {
    ec := EventCenter{}
    ec.observers = make([]Observer, 0)
    return &ec
}

测试

测试观察者设计模式的实现

func main() {
    eventCenter := NewEventCenter()
    receiver1 := EventReceiver{}
    receiver2 := EventReceiver{}

    eventCenter.Register(&receiver1)
    eventCenter.Register(&receiver2)

    eventCenter.Notify(Event{"hello golang"})
    eventCenter.UnRegister(&receiver1)

    eventCenter.Notify(Event{"hello docker"})
}

结果

Receiver receive: hello golang
Receiver receive: hello golang
Receiver receive: hello docker
文章目录