如何在Golang中实现工厂模式_动态创建不同类型对象

21次阅读

工厂模式的核心思想是用函数根据参数返回实现同一接口的具体类型实例。在go中通过接口定义行为、函数动态创建对象,支持简单工厂和可扩展的注册式工厂,实现创建与使用的解耦。

如何在Golang中实现工厂模式_动态创建不同类型对象

工厂模式的核心思想

工厂模式解决的是对象创建与使用分离的问题。在 Go 中没有类和继承,所以不依赖传统面向对象的抽象类或接口继承体系,而是通过接口定义行为、函数返回具体类型来实现“动态创建”。关键在于:**用一个函数根据参数决定返回哪个具体类型的实例,且这些类型都实现了同一接口**。

定义统一接口和具体类型

先设计一个公共接口,比如 Shape,再实现多个结构体(如 Circle、Rectangle)并为它们实现该接口的方法:

// 定义接口
type Shape Interface {
  Area() float64
  Name() String
}

// 具体类型
type Circle Struct {
  Radius float64
}

func (c Circle) Area() float64 { return 3.14 * c.Radius * c.Radius }
func (c Circle) Name() string { return “circle” }

type Rectangle struct {
  Width, Height float64
}

func (r Rectangle) Area() float64 { return r.Width * r.Height }
func (r Rectangle) Name() string { return “rectangle” }

实现简单工厂函数

写一个工厂函数,接收类型标识(如字符串),返回对应的具体类型实例(注意返回接口类型):

func NewShape(shapeType string) Shape {
  switch shapeType {
  case “circle”:
    return Circle{Radius: 1.0}
  case “rectangle”:
    return Rectangle{Width: 2.0, Height: 3.0}
  default:
    return Circle{Radius: 0} // 或 panic / 返回零值 / 错误处理
  }
}

调用时无需关心内部构造细节:

立即学习go语言免费学习笔记(深入)”;

shape := NewShape(“rectangle”)
fmt.Println(shape.Name(), shape.Area()) // rectangle 6

支持扩展与错误处理的进阶工厂

实际项目中建议返回 (Shape, Error) 并支持注册新类型,避免每次修改 switch。可用 map + 函数映射模拟“注册式工厂”:

var shapeCreators = map[string]func() Shape{
  “circle”: func() Shape { return Circle{Radius: 1.0} },
  “rectangle”: func() Shape { return Rectangle{Width: 2.0, Height: 3.0} },
}

func RegisterShape(name string, creator func() Shape) {
  shapeCreators[name] = creator
}

func NewShape(name string) (Shape, error) {
  creator, ok := shapeCreators[name]
  if !ok {
    return nil, fmt.Errorf(“unknown shape type: %s”, name)
  }
  return creator(), nil
}

这样新增类型只需调用 RegisterShape(“triangle”, func() Shape {…}),无需改动原有工厂逻辑。

text=ZqhQzanResources