工厂模式
本课属于 Coddy GO 学习旅程的“面向对象编程”单元。第 87 课,共 107 课。
工厂模式将对象创建委托给单独的函数或方法,让你无需暴露创建逻辑即可创建实例。与控制实例数量的单例模式不同,工厂模式侧重于根据输入参数灵活地创建对象。
在 Go 中,工厂通常是一个返回接口类型的函数,让你可以通过统一的 API 创建不同的具体类型:
type Notifier interface {
Send(message string) string
}
type EmailNotifier struct{}
type SMSNotifier struct{}
func (e EmailNotifier) Send(message string) string {
return "Email: " + message
}
func (s SMSNotifier) Send(message string) string {
return "SMS: " + message
}
func NewNotifier(notifierType string) Notifier {
switch notifierType {
case "email":
return EmailNotifier{}
case "sms":
return SMSNotifier{}
default:
return EmailNotifier{}
}
}工厂函数 NewNotifier 封装了要创建哪种具体类型的决策。客户端代码只使用 Notifier 接口,无需了解具体实现:
notifier := NewNotifier("sms")
result := notifier.Send("Hello!") // "SMS: Hello!"当你需要根据运行时条件创建对象、集中处理复杂的初始化逻辑,或轻松添加新类型而不修改客户端代码时,这种模式尤其有用。只需添加一个实现该接口的新结构体,并更新工厂函数。
挑战
简单让我们使用工厂模式构建一个文档转换系统!你将创建一个工厂,根据目标格式生成不同的文档转换器,让客户端代码通过统一的接口使用任意转换器。
你将把代码分成两个文件:
converter.go:定义转换器接口和具体实现。创建一个
Converter接口,其中包含一个方法Convert(content string) string,该方法接收文档内容并返回转换后的输出。实现三种转换器类型:
PDFConverter:它的Convert方法返回PDF: [content]HTMLConverter:它的Convert方法返回HTML: <p>[content]</p>MarkdownConverter:它的Convert方法返回MD: # [content]
创建一个工厂函数
NewConverter(format string) Converter,根据格式字符串(pdf、html或markdown)返回对应的转换器。对于任何无法识别的格式,默认返回一个PDFConverter。main.go:使用工厂创建转换器并处理文档。读取格式类型和文档内容。使用工厂创建对应的转换器,然后转换内容并打印结果。
将提供以下输入:
- 第 1 行:格式类型(
pdf、html、markdown或其他内容) - 第 2 行:要转换的文档内容
例如,给定:
html
Welcome to Go Programming你的输出应为:
HTML: <p>Welcome to Go Programming</p>再例如,给定:
markdown
Chapter One你的输出应为:
MD: # Chapter One再例如,给定:
pdf
Annual Report 2024你的输出应为:
PDF: Annual Report 2024再例如,给定:
docx
Meeting Notes你的输出应为:
PDF: Meeting Notes注意,主代码不需要了解具体的转换器类型。它只需向工厂请求一个转换器,然后使用接口即可。这样一来,之后添加新格式就很容易,而且无需更改客户端代码!
亲手试试
package main
import (
"bufio"
"fmt"
"os"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
// 读取格式类型
scanner.Scan()
format := scanner.Text()
// 读取文档内容
scanner.Scan()
content := scanner.Text()
// TODO:使用工厂创建合适的转换器
// TODO:转换内容并打印结果
fmt.Println(result)
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: Go 在线编译器