在 Go 语言中,由于缺少传统的构造函数,通过 NewXXX 函数初始化对象是标准实践。当这个函数返回接口类型时,它就构成了一个典型的简单工厂模式。因此,简单工厂模式在 Go 中不仅是一种设计模式,更是一种被广泛采用的代码组织方式。
不废话, 直接上干货。
下面我将以关系图方式, 举例 “动物类” 来生动演绎简单工厂模式的样子以及配套演示代码。
┌──────────────────┐
│ AnimalsInterface │
├──────────────────┤
│ +Say() string │
└─────────┬────────┘
│
│ 实现(implements)
┌──────────────┼──────────────┐
│ │ │
┌──────▼─────┐ ┌─────▼──────┐ ┌─────▼──────┐
│ Cat │ │ Dog │ │ Default │
├────────────┤ ├────────────┤ ├────────────┤
│ +Say() │ │ +Say() │ │ +Say() │
│ 返回"喵喵喵"│ │ 返回"汪汪汪"│ │ 返回"默认" │
└────────────┘ └────────────┘ └────────────┘
▲ ▲ ▲
│ │ │
└──────┬───────┴──────┬───────┘
│ │
┌─────▼───────────────▼─────┐
│ NewAnimals(name) │
│ AnimalsInterface │
│ │
│ 根据name创建对应的实例 │
└───────────────────────────┘
package main
// AnimalType 定义动物类型枚举
type AnimalType string
const (
// CatType 猫
CatType AnimalType = "cat"
// DogType 狗
DogType AnimalType = "dog"
)
func main() {
// 创建动物: 猫
var animalsCat = NewAnimals(CatType)
// 调用动物叫声
println(animalsCat.Say())
// 创建动物: 狗
var animalsDog = NewAnimals(DogType)
// 调用动物叫声
println(animalsDog.Say())
// 创建默认动物
var animalsDefault = NewAnimals("default")
// 调用动物叫声
println(animalsDefault.Say())
}
// AnimalsInterface 定义动物接口 (定义外部可见调用, 隐藏内部实现细节)
type AnimalsInterface interface {
// Say 定义动物叫声的方法, 返回动物叫声
Say() string
}
// NewAnimals 创建动物
func NewAnimals(animalType AnimalType) AnimalsInterface {
switch animalType {
case CatType:
return &Cat{}
case DogType:
return &Dog{}
default:
return &Default{}
}
}
// Cat 定义猫
type Cat struct{}
// Say 猫叫声
func (c *Cat) Say() string {
return "喵喵喵"
}
// Dog 定义狗
type Dog struct{}
// Say 狗叫声
func (d *Dog) Say() string {
return "汪汪汪"
}
// Default 定义默认动物
type Default struct{}
// Say 默认动物叫声
func (d *Default) Say() string {
return "默认叫声"
}
✅ 设计模式优势
| 优势 | 描述 |
|---|---|
| 封装性 | 将对象创建逻辑集中管理 |
| 解耦性 | 客户端不依赖具体类,只依赖接口 |
| 扩展性 | 新增动物类型只需修改工厂函数 |
| 简洁性 | 客户端调用简单,无需了解创建细节 |
🔧 适用场景
✰ - 需要创建的对象种类较少
✰ - 客户端不关心对象创建过程
✰ - 需要统一管理对象的创建逻辑
🚀 扩展提示
添加新动物只需如下两个步骤
★ 创建新结构体并实现接口
★ 在工厂函数中添加新的 case 分支