返回

Go语言设计模式:23种经典解决方案,助你构建优雅代码

后端

23种经典设计模式与Go语言实现

设计模式 是经过实践验证的最佳实践,可帮助我们在软件开发中构建可重用、可维护和可扩展的代码。本文将介绍23种经典设计模式,并使用Go语言进行实现。

1. 创建型模式

1.1 工厂模式

工厂模式提供了一个创建对象的接口,它允许我们在无需指定具体类的情况下创建不同类型的对象。

type Factory interface {
    CreateProduct() Product
}

type Product interface {
    GetName() string
}

type ConcreteFactory1 struct{}

func (f *ConcreteFactory1) CreateProduct() Product {
    return &ConcreteProduct1{}
}

type ConcreteFactory2 struct{}

func (f *ConcreteFactory2) CreateProduct() Product {
    return &ConcreteProduct2{}
}

type ConcreteProduct1 struct{}

func (p *ConcreteProduct1) GetName() string {
    return "ConcreteProduct1"
}

type ConcreteProduct2 struct{}

func (p *ConcreteProduct2) GetName() string {
    return "ConcreteProduct2"
}

func main() {
    factory1 := &ConcreteFactory1{}
    product1 := factory1.CreateProduct()
    fmt.Println(product1.GetName()) // Output: ConcreteProduct1

    factory2 := &ConcreteFactory2{}
    product2 := factory2.CreateProduct()
    fmt.Println(product2.GetName()) // Output: ConcreteProduct2
}

1.2 抽象工厂模式

抽象工厂模式提供了一个创建一系列相关对象的接口,这些对象都属于一个共同的主题。

type AbstractFactory interface {
    CreateProductA() ProductA
    CreateProductB() ProductB
}

type ProductA interface {
    GetName() string
}

type ProductB interface {
    GetName() string
}

type ConcreteFactory1 struct{}

func (f *ConcreteFactory1) CreateProductA() ProductA {
    return &ConcreteProductA1{}
}

func (f *ConcreteFactory1) CreateProductB() ProductB {
    return &ConcreteProductB1{}
}

type ConcreteFactory2 struct{}

func (f *ConcreteFactory2) CreateProductA() ProductA {
    return &ConcreteProductA2{}
}

func (f *ConcreteFactory2) CreateProductB() ProductB {
    return &ConcreteProductB2{}
}

type ConcreteProductA1 struct{}

func (p *ConcreteProductA1) GetName() string {
    return "ConcreteProductA1"
}

type ConcreteProductA2 struct{}

func (p *ConcreteProductA2) GetName() string {
    return "ConcreteProductA2"
}

type ConcreteProductB1 struct{}

func (p *ConcreteProductB1) GetName() string {
    return "ConcreteProductB1"
}

type ConcreteProductB2 struct{}

func (p *ConcreteProductB2) GetName() string {
    return "ConcreteProductB2"
}

func main() {
    factory1 := &ConcreteFactory1{}
    productA1 := factory1.CreateProductA()
    productB1 := factory1.CreateProductB()
    fmt.Println(productA1.GetName(), productB1.GetName()) // Output: ConcreteProductA1 ConcreteProductB1

    factory2 := &ConcreteFactory2{}
    productA2 := factory2.CreateProductA()
    productB2 := factory2.CreateProductB()
    fmt.Println(productA2.GetName(), productB2.GetName()) // Output: ConcreteProductA2 ConcreteProductB2
}

1.3 单例模式

单例模式确保创建一个类的只有一个实例,并提供一个全局访问点来获取该实例。

type Singleton struct {
    instance *Singleton
}

func GetInstance() *Singleton {
    if instance == nil {
        instance = &Singleton{}
    }
    return instance
}

func main() {
    singleton1 := GetInstance()
    singleton2 := GetInstance()

    fmt.Println(singleton1 == singleton2) // Output: true
}

1.4 建造者模式

建造者模式将一个复杂对象的构建与它的表示分离,使同一个构建过程可以创建不同的表示。

type Builder interface {
    SetPartA()
    SetPartB()
    SetPartC()
    GetProduct() Product
}

type Product interface {
    GetParts() []string
}

type ConcreteBuilder1 struct {
    parts []string
}

func (b *ConcreteBuilder1) SetPartA() {
    b.parts = append(b.parts, "PartA")
}

func (b *ConcreteBuilder1) SetPartB() {
    b.parts = append(b.parts, "PartB")
}

func (b *ConcreteBuilder1) SetPartC() {
    b.parts = append(b.parts, "PartC")
}

func (b *ConcreteBuilder1) GetProduct() Product {
    return &ConcreteProduct1{parts: b.parts}
}

type ConcreteBuilder2 struct {
    parts []string
}

func (b *ConcreteBuilder2) SetPartA() {
    b.parts = append(b.parts, "PartA")
}

func (b *ConcreteBuilder2) SetPartB() {
    b.parts = append(b.parts, "PartB")
}

func (b *ConcreteBuilder2) SetPartC() {
    b.parts = append(b.parts, "PartC")
}

func (b *ConcreteBuilder2) GetProduct() Product {
    return &ConcreteProduct2{parts: b.parts}
}

type ConcreteProduct1 struct {
    parts []string
}

func (p *ConcreteProduct1) GetParts() []string {
    return p.parts
}

type ConcreteProduct2 struct {
    parts []string
}

func (p *ConcreteProduct2) GetParts() []string {
    return p.parts
}

func main() {
    builder1 := &ConcreteBuilder1{}
    builder1.SetPartA()
    builder1.SetPartB()
    builder1.SetPartC()
    product1 := builder1.GetProduct()
    fmt.Println(product1.GetParts()) // Output: [PartA PartB PartC]

    builder2 := &ConcreteBuilder2{}
    builder2.SetPartA()
    builder2.SetPartB()
    builder2.SetPartC()
    product2 := builder2.GetProduct()
    fmt.Println(product2.GetParts()) // Output: [PartA PartB PartC]
}

2. 结构型模式

2.1 适配器模式

适配器模式将一个类的接口转换成另一个类所期望的接口,使得原本不兼容的类可以一起工作。

type Target interface {
    Request() string
}

type Adaptee interface {
    SpecificRequest() string
}

type Adapter struct {
    adaptee Adaptee
}

func (a *Adapter) Request() string {
    return a.adaptee.SpecificRequest()
}

type ConcreteAdaptee struct{}

func (c *ConcreteAdaptee) SpecificRequest() string {
    return "Specific request"
}

func main() {
    target := &Adapter{adaptee: &ConcreteAdaptee{}}
    fmt.Println(target.Request()) // Output: Specific request
}

2.2 桥接模式

桥接模式将一个类的接口与其实现分离,使这两者可以独立变化。

type Abstraction interface {
    Operation() string
}

type Implementor interface {
    OperationImp() string
}

type ConcreteAbstraction struct {
    implementor Implementor
}

func (c *ConcreteAbstraction) Operation() string {
    return c.implementor.OperationImp()
}

type ConcreteImplementorA struct{}

func (c *ConcreteImplementorA) OperationImp() string {
    return "Implementation A"
}

type ConcreteImplementorB struct{}

func (c *ConcreteImplementorB) OperationImp() string {
    return "Implementation B"
}

func main() {
    abstraction := &ConcreteAbstraction{implementor: &ConcreteImplementorA{}}
    fmt.Println(abstraction.Operation()) // Output: Implementation A

    abstraction.implementor = &ConcreteImplementorB{}
    fmt.Println(abstraction.Operation()) // Output: Implementation B
}

2.3 组合模式

组合模式将对象组织成树形结构,从而可以对它们进行统一的处理。

type Component interface {
    Operation()
}

type Composite struct {
    children []Component
}

func (c *Composite) Operation() {
    for _, child := range c.children {
        child.Operation()
    }
}

type Leaf struct {}

func (l *Leaf) Operation() {
    fmt.Println("Leaf operation")