Golang设计模式

2024年1月17日 · 1971 字 · 4 分钟 · 设计模式

Golang设计模式

前言

  • Go语言鼓励更简单、更直接的方式来解决问题,倾向于使用组合而不是继承

基本的Go语言设计模式

创建型设计模式

  1. 单例模式(Singleton Pattern):确保一个类只有一个实例,并提供全局访问点。
  2. 工厂方法模式(Factory Method Pattern):定义一个用于创建对象的接口,让子类决定实例化哪一个类。
  3. 抽象工厂模式(Abstract Factory Pattern):围绕一个超级工厂创建其他工厂,该超级工厂又称为其他工厂的工厂。
  4. 建造者模式(Builder Pattern):使用多个简单的对象一步一步构建成一个复杂的对象。

结构型设计模式

  1. 适配器模式(Adapter Pattern):将一个类的接口转换成客户希望的另一个接口,使原本由于接口不兼容而不能一起工作的那些类能一起工作。
  2. 装饰器模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能来说,相比生成子类更为灵活。
  3. 代理模式(Proxy Pattern):为其他对象提供一种代理以控制对这个对象的访问。
  4. 组合模式(Composite Pattern):将对象组合成树形结构以表示部分整体的层次结构,使得用户对单个对象和组合对象的使用具有一致性。

行为型设计模式

  1. 策略模式(Strategy Pattern):定义一系列算法,把它们一个个封装起来,并且使它们可相互替换。
  2. 观察者模式(Observer Pattern):当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随之变化。
  3. 命令模式(Command Pattern):将一个请求封装成一个对象,从而使你可用不同的请求对客户进行参数化。
  4. 模板方法模式(Template Method Pattern):定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。

并发型设计模式

  1. 生产者-消费者模式(Producer-Consumer Pattern):通过一个共享的缓冲区来解耦生产者和消费者的运行。
  2. 读写锁模式(Read-Write Lock Pattern):允许多个读取者或一个写入者访问数据。

按使用频率优先级排序

  1. 工厂方法模式(Factory Method Pattern) 因为Go语言没有构造函数,通常使用工厂方法来进行对象的创建和初始化。
package factory

type IProduct interface {
    Use() string
}

type ProductA struct{}

func (p ProductA) Use() string {
    return "ProductA"
}

type ProductB struct{}

func (p ProductB) Use() string {
    return "ProductB"
}

func NewProduct(t string) IProduct {
    if t == "A" {
        return ProductA{}
    } else if t == "B" {
        return ProductB{}
    }
    return nil
}
  1. 接口模式(Interface Pattern) 接口在Go语言中非常重要,它们支持隐式实现和多态性,是许多设计模式实现的基础。
package main

import "fmt"

// Animal 接口定义了所有动物应该具备的行为
type Animal interface {
	Speak() string
}

// Dog 结构体代表狗这个动物
type Dog struct{}

// Dog 实现了 Animal 接口的 Speak 方法
func (d Dog) Speak() string {
	return "Woof!"
}

// Cat 结构体代表猫这个动物
type Cat struct{}

// Cat 实现了 Animal 接口的 Speak 方法
func (c Cat) Speak() string {
	return "Meow!"
}

func main() {
	// 创建一系列动物
	animals := []Animal{Dog{}, Cat{}}
	
	// 通过 Animal 接口与不同的动物对象交互
	for _, animal := range animals {
		fmt.Println(animal.Speak())
	}
}
  1. 组合模式(Composite Pattern) Go语言倾向于使用组合而不是继承,组合模式允许用户将对象组织成树结构来表示整体-部分的层次结构。
package main

import (
	"fmt"
)

// Component 定义了组合中的对象接口
type Component interface {
	Search(string)
}

// File 实现了Component接口,代表叶节点对象
type File struct {
	name string
}

// Search 在File中实现,输出文件名
func (f *File) Search(keyword string) {
	fmt.Printf("Searching for keyword %s in file %s
", keyword, f.name)
}

// Folder 实现了Component接口,代表容器节点对象,可以包含File或者其他Folder
type Folder struct {
	components []Component
	name       string
}

// Search 在Folder中实现,递归地调用其组件的Search方法
func (f *Folder) Search(keyword string) {
	fmt.Printf("Searching recursively for keyword %s in folder %s
", keyword, f.name)
	for _, composite := range f.components {
		composite.Search(keyword)
	}
}

// Add 方法添加组件到文件夹
func (f *Folder) Add(c Component) {
	f.components = append(f.components, c)
}

func main() {
	// 创建文件和文件夹,并组合成树形结构
	file1 := &File{name: "File1"}
	file2 := &File{name: "File2"}
	file3 := &File{name: "File3"}

	folder1 := &Folder{name: "Folder1"}
	folder2 := &Folder{name: "Folder2"}

	folder1.Add(file1)

	folder2.Add(file2)
	folder2.Add(file3)
	folder2.Add(folder1)

	// 执行搜索,可以看到它递归地搜索整个结构
	folder2.Search("rose")
}
  1. 单例模式(Singleton Pattern) 单例模式用于确保程序中一个类只有一个实例,这在Go中通常是通过全局变量和sync包中的Once来实现的。
package singleton

import "sync"

type singleton struct{}

var instance *singleton
var once sync.Once

func GetInstance() *singleton {
    once.Do(func() {
        instance = &singleton{}
    })
    return instance
}
  1. 策略模式(Strategy Pattern) 策略模式允许在运行时选择算法或行为,非常适合Go语言的接口概念。
pickwish
  1. 装饰器模式(Decorator Pattern) Go语言的装饰器模式通常利用闭包和匿名函数实现,用于动态地给函数增加功能。

  2. 观察者模式(Observer Pattern) 当一个对象状态变化时,依赖于它的所有对象都会得到通知和更新。在Go中,通常利用channel和goroutines实现事件监听和通知功能。

  3. 适配器模式(Adapter Pattern) 适配器可以解决接口不兼容问题,让原本不兼容的接口能够一起工作,对于整合不同的系统组件非常有用。

  4. 代理模式(Proxy Pattern) 代理模式常用于懒加载、访问控制、日志等场景,可以在不改变对象类的前提下,为对象添加额外功能。

参考资料