Go语言常用的设计模式

以下是Go语言中24种设计模式的详细说明及代码示例,结合Go语言特性(接口、组合、并发)进行实现,分为创建型、结构型、行为型和Go特有模式四类:


一、创建型模式(6种)​

  1. 单例模式(Singleton)​

    • 核心:确保全局唯一实例。
    • Go实现sync.Once保证线程安全。
    Go 复制代码
    package singleton
    import "sync"
    type Singleton struct{}
    var instance *Singleton
    var once sync.Once
    func GetInstance() *Singleton {
        once.Do(func() { instance = &Singleton{} })
        return instance
    }

    场景​:全局配置对象、数据库连接池。

  2. 工厂方法模式(Factory Method)​

    • 核心:由子类决定实例化类。
    • Go实现 :返回接口的函数(如 NewAPI())。
    Go 复制代码
    type API interface { Say(name string) string }
    func NewAPI(t int) API {
        switch t {
            case 1: return &hiAPI{}
            case 2: return &helloAPI{}
        }
        return nil
    }

    场景​:数据库驱动切换(MySQL/Postgres)。

  3. 抽象工厂模式(Abstract Factory)​

    • 核心:创建一组相关对象(如食品+药品)。
    Go 复制代码
    type Factory interface {
        NewFood() Food
        NewDrug() Drug
    }
    type FirstFactory struct{}
    func (f FirstFactory) NewFood() Food { return &meat{} }

    场景​:跨平台UI组件库(按钮+文本框组合)。

  4. 建造者模式(Builder)​

    • 核心:分步构建复杂对象(如SQL查询构造器)。
    Go 复制代码
    type Builder interface { Part1(); Part2() }
    type Director struct{ builder Builder }
    func (d *Director) Construct() { 
        d.builder.Part1()
        d.builder.Part2()
    }

    场景​:HTTP请求构造、配置对象组装。

  5. 原型模式(Prototype)​

    • 核心:通过克隆创建新对象。
    • Go实现 :实现 Clone() interface{} 方法。
    Go 复制代码
    type Prototype interface { Clone() Prototype }
    type File struct{ name string }
    func (f *File) Clone() Prototype { return &File{name: f.name} }

    场景​:游戏角色模板复制、配置模板复用。

  6. 对象池模式(Object Pool)​

    • 核心:复用对象减少开销。
    • Go实现sync.Pool
    Go 复制代码
    var ReqPool = sync.Pool{
        New: func() any { return &http.Request{} },
    }
    func GetRequest() *http.Request {
        return ReqPool.Get().(*http.Request)
    }

    场景​:高并发请求处理(如Gin的Context池)。


二、结构型模式(7种)​

  1. 适配器模式(Adapter)​

    • 核心:转换接口兼容旧系统。
    Go 复制代码
    type Adaptee interface { SpecificRequest() string }
    type Adapter struct{ Adaptee }
    func (a *Adapter) Request() string { 
        return a.SpecificRequest() 
    }

    场景​:第三方日志库接入系统。

  2. 桥接模式(Bridge)​

    • 核心:分离抽象与实现(如形状+渲染引擎)。
    Go 复制代码
    type DrawAPI interface { DrawCircle(radius float64) }
    type CircleShape struct{ drawAPI DrawAPI }  // 组合实现解耦

    场景​:跨平台绘图库。

  3. 组合模式(Composite)​

    • 核心:树形结构处理部分-整体关系。
    Go 复制代码
    type Component interface { Search(keyword string) }
    type Folder struct{ children []Component }  // 可包含其他Component

    场景​:文件系统、UI组件嵌套。

  4. 装饰器模式(Decorator)​

    • 核心:动态扩展功能(不修改原对象)。
    Go 复制代码
    type Component interface { Operation() string }
    type LogDecorator struct{ component Component }
    func (d *LogDecorator) Operation() string {
        log.Println("start")
        return d.component.Operation()
    }

    场景​:HTTP中间件链、日志增强。

  5. 外观模式(Facade)​

    • 核心:简化复杂子系统调用。
    Go 复制代码
    func ProcessOrder() {  // 封装支付、库存、通知
        ValidatePayment()
        ReserveStock()
        NotifyUser()
    }

    场景​:电商下单接口、API网关。

  6. 享元模式(Flyweight)​

    • 核心:共享对象减少内存(如缓存颜色)。
    Go 复制代码
    var colorFactory = make(map[string]*Color)
    func GetColor(name string) *Color {
        if c, ok := colorFactory[name]; ok { return c }
        c := &Color{Name: name}
        colorFactory[name] = c
        return c
    }

    场景​:游戏粒子系统、文档编辑器格式复用。

  7. 代理模式(Proxy)​

    • 核心:控制对象访问(如缓存代理)。
    Go 复制代码
    type Image interface{ Display() }
    type ProxyImage struct{ realImage *RealImage }  // 延迟加载
    func (p *ProxyImage) Display() {
        if p.realImage == nil { p.realImage = &RealImage{} }
        p.realImage.Display()
    }

    场景​:数据库访问代理、RPC客户端。


三、行为型模式(7种)​

  1. 责任链模式(Chain of Responsibility)​

    • 核心:多个处理器链式处理请求。
    Go 复制代码
    type Handler interface { Handle(amount int) }
    type Manager struct{ next Handler }
    func (m *Manager) Handle(amount int) {
        if amount <= 1000 { fmt.Println("Manager审批") } 
        else { m.next.Handle(amount) }
    }

    场景​:审批流程、HTTP中间件链。

  2. 命令模式(Command)​

    • 核心:封装请求为对象(支持撤销/重做)。
    Go 复制代码
    type Command interface{ Execute() }
    type LightOnCommand struct{ light *Light }  // Light为实际接收者
    func (c *LightOnCommand) Execute() { c.light.On() }

    场景​:GUI按钮操作、事务队列。

  3. 观察者模式(Observer)​

    • 核心:一对多事件通知。
    Go 复制代码
    type Subject struct{ observers []Observer }
    func (s *Subject) Notify() {
        for _, o := range s.observers { o.Update() }
    }

    场景​:订单状态更新、微服务事件总线。

  4. 策略模式(Strategy)​

    • 核心:动态切换算法(如支付方式)。
    Go 复制代码
    type PaymentStrategy interface{ Pay(amount float64) }
    type Alipay struct{}
    func (a Alipay) Pay(amount float64) { 
        fmt.Printf("支付宝支付%.2f元", amount)
    }

    场景​:支付策略、排序算法切换。

  5. 模板方法模式(Template Method)​

    • 核心:父类定义算法骨架。
    Go 复制代码
    type Game interface{ Init(); Start(); End() }
    type Chess struct{}
    func (c *Chess) Init() { fmt.Println("初始化棋盘") }  // 子类实现步骤

    场景​:插件生命周期管理、业务流程标准化。

  6. 访问者模式(Visitor)​

    • 核心:解耦数据结构与操作。
    Go 复制代码
    type Visitor interface{ VisitFile(f *File) }
    type File struct{}
    func (f *File) Accept(v Visitor) { v.VisitFile(f) }

    场景​:AST解析、报表导出。

  7. 状态模式(State)​

    • 核心:封装状态行为(如订单状态机)。
    Go 复制代码
    type OrderState interface{ Cancel() }
    type ShippedState struct{} 
    func (s *ShippedState) Cancel() { fmt.Println("已发货订单需退款") }

    场景​:游戏角色状态、工作流引擎。


四、Go语言特有模式(4种)​

  1. 函数选项模式(Functional Options)​

    • 核心:优雅处理可选参数。
    Go 复制代码
    type Option func(*Server)
    func WithPort(port int) Option {
        return func(s *Server) { s.Port = port }
    }
    func NewServer(opts ...Option) *Server {
        s := &Server{Port: 8080} // 默认值
        for _, opt := range opts { opt(s) } // 应用选项
        return s
    }

    场景​:配置对象初始化(如gRPC客户端)。

  2. 并发模式(Concurrency Patterns)​

    • 核心goroutine + channel 解耦任务。
    Go 复制代码
    func worker(jobs <-chan int, results chan<- int) {
        for j := range jobs { results <- j * 2 }
    }

    场景​:管道过滤、扇出/扇入任务。

  3. 中间件模式(Middleware)​

    • 核心:链式处理函数(如HTTP中间件)。
    Go 复制代码
    type Middleware func(http.Handler) http.Handler
    func Logging(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            log.Println(r.URL)
            next.ServeHTTP(w, r)
        })
    }

    场景​:Web框架中间件、日志拦截。

  4. 依赖注入模式(Dependency Injection)​

    • 核心:通过接口注入依赖。
    Go 复制代码
    type DB interface{ Query() }
    type Service struct{ db DB }  // 依赖接口而非具体类

    场景​:单元测试Mock、模块解耦。


五、模式选择指南

场景 推荐模式
全局唯一资源 单例模式
多态对象创建 工厂方法/抽象工厂
复杂对象构造 建造者模式
动态扩展功能 装饰器/责任链
算法灵活切换 策略模式
简化复杂子系统 外观模式
可选参数配置 函数选项模式

Go语言设计哲学​:

  1. 组合优于继承:通过接口和结构体嵌入实现复用
  2. 显式依赖注入:避免全局状态,提升可测试性
  3. 简洁性优先:避免过度设计,如命令模式可直接用函数类型替代
  4. 并发原生支持:用channel替代回调地狱

总结:所有示例均可在实际项目中直接应用,建议结合业务场景选择模式,避免为了模式而模式。

相关推荐
rockmelodies4 分钟前
RSA 解密逻辑
开发语言·python
pointers_syc38 分钟前
【设计模式】2.策略模式
java·设计模式·策略模式
澡点睡觉43 分钟前
golang的包和闭包
开发语言·后端·golang
Dxy12393102162 小时前
python创建一个excel文件
开发语言·python·excel
朝朝又沐沐2 小时前
算法竞赛阶段二-数据结构(40)数据结构栈的STL
开发语言·数据结构·c++·算法
深海潜水员2 小时前
【Unity】背包系统 + 物品管理窗口 (上)
开发语言·vscode·游戏·unity·c#·游戏引擎
德育处主任Pro3 小时前
p5.js 用 beginGeometry () 和 endGeometry () 打造自定义 3D 模型
开发语言·javascript·3d
kyranhan3 小时前
C#程序本地运行正常,通过网络下载报错:FileLoadException:“未能加载文件或程序集“xxx.dll”或它的某一个依赖项。
开发语言·c#·wpf