简单工厂模式虽非GoF 23种设计模式之一,但通过接口定义行为、结构体实现具体逻辑、工厂函数统一创建并返回接口实例,实现了对象创建逻辑的封装与解耦。

简单工厂模式不是GoF 23种设计模式之一,但它是一种实用的封装对象创建逻辑的方式。Golang没有类和构造函数,但可以通过函数、结构体和接口自然实现类似效果——核心是把“创建什么类型”的判断逻辑集中到一个工厂函数中,对外隐藏具体类型和初始化细节。
定义统一接口,让不同实现可互换
先定义一个接口,描述所有产品共有的行为。比如做一个日志记录器工厂,支持控制台、文件、网络三种输出方式:
log.go
type Logger interface {Log(message string)
}
实现具体类型,各自封装内部逻辑
每个具体日志器实现 Logger 接口,内部处理各自的写入方式:
立即学习“go语言免费学习笔记(深入)”;
console_logger.go
type ConsoleLogger struct{}func (c *ConsoleLogger) Log(message string) {
fmt.Println("[CONSOLE]", message)
}
file_logger.go
type FileLogger struct {filename string
}
func NewFileLogger(filename string) *FileLogger {
return &FileLogger{filename: filename}
}
func (f *FileLogger) Log(message string) {
f.writeToFile(message) // 省略具体写入逻辑
}
编写工厂函数,统一管理创建逻辑
工厂函数接收参数(如类型名或配置),返回接口类型实例。调用方不关心具体结构体,只依赖 Logger 接口:
logger_factory.go
type LoggerType stringconst (
ConsoleLoggerType LoggerType = "console"
FileLoggerType LoggerType = "file"
NetworkLoggerType LoggerType = "network"
)
func NewLogger(loggerType LoggerType, config map[string]string) Logger {
switch loggerType {
case ConsoleLoggerType:
return &ConsoleLogger{}
case FileLoggerType:
return NewFileLogger(config["filename"])
case NetworkLoggerType:
return &NetworkLogger{addr: config["addr"]}
default:
return &ConsoleLogger{} // 默认兜底
}
}
使用时只需调用工厂,解耦创建与使用
业务代码不再 new 具体类型,而是通过工厂获取实例,后续扩展新日志器也不影响原有调用:
func main() {logger := NewLogger(ConsoleLoggerType, nil)
logger.Log("Hello from console")
fileLogger := NewLogger(FileLoggerType, map[string]string{"filename": "app.log"})
fileLogger.Log("Saved to file")
}
- 新增日志器只需实现 Logger 接口 + 在工厂中加 case 分支
- 调用方无感知变化,无需修改 import 或初始化语句
- 配置可灵活传入(如 map、struct、option 函数),提升扩展性










