设计艺术之一简单工厂模式

22 阅读2分钟

在 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 分支