diff --git a/README.md b/README.md index f40320e..29f0d9d 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,9 @@ ### 8. 短信工具 (sms) 提供阿里云短信发送功能,支持模板短信和批量发送,使用Go标准库实现。 +### 9. 工厂工具 (factory) +提供从配置直接创建已初始化客户端对象的功能,避免调用方重复实现创建逻辑。 + ## 安装 ### 1. 配置私有仓库(重要) @@ -61,6 +64,7 @@ go get git.toowon.com/jimmy/go-commom - [存储工具文档](./docs/storage.md) - [邮件工具文档](./docs/email.md) - [短信工具文档](./docs/sms.md) +- [工厂工具文档](./docs/factory.md) ### 快速示例 @@ -175,6 +179,26 @@ smsClient.SendSimple( ) ``` +#### 使用工厂直接获取客户端(推荐) +```go +import ( + "git.toowon.com/jimmy/go-commom/config" + "git.toowon.com/jimmy/go-commom/factory" +) + +// 加载配置并创建工厂 +cfg, _ := config.LoadFromFile("./config.json") +fac := factory.NewFactory(cfg) + +// 直接获取已初始化的客户端(无需重复实现创建逻辑) +emailClient, _ := fac.GetEmailClient() +smsClient, _ := fac.GetSMSClient() + +// 直接使用 +emailClient.SendSimple(...) +smsClient.SendSimple(...) +``` + 更多示例请查看 [examples](./examples/) 目录。 ## 版本 diff --git a/docs/README.md b/docs/README.md index 6c6eaa2..a61aad8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -10,6 +10,7 @@ - [存储工具](./storage.md) - 文件上传和查看(OSS、MinIO) - [邮件工具](./email.md) - SMTP邮件发送 - [短信工具](./sms.md) - 阿里云短信发送 +- [工厂工具](./factory.md) - 从配置直接创建已初始化客户端对象 ## 快速开始 diff --git a/docs/factory.md b/docs/factory.md new file mode 100644 index 0000000..5e784f4 --- /dev/null +++ b/docs/factory.md @@ -0,0 +1,203 @@ +# 工厂工具文档 + +## 概述 + +工厂工具提供了从配置直接创建已初始化的客户端对象的功能,避免调用方重复实现创建逻辑。 + +## 功能特性 + +- 从配置直接创建已初始化的客户端对象 +- 统一的工厂接口 +- 避免调用方重复实现创建逻辑 + +## 使用方法 + +### 1. 创建工厂实例 + +```go +import ( + "git.toowon.com/jimmy/go-commom/config" + "git.toowon.com/jimmy/go-commom/factory" +) + +// 加载配置 +cfg, err := config.LoadFromFile("./config.json") +if err != nil { + log.Fatal(err) +} + +// 创建工厂实例 +fac := factory.NewFactory(cfg) +``` + +### 2. 获取邮件客户端(已初始化) + +```go +// 直接获取已初始化的邮件客户端 +emailClient, err := fac.GetEmailClient() +if err != nil { + log.Fatal(err) +} + +// 直接使用,无需再创建 +err = emailClient.SendSimple( + []string{"recipient@example.com"}, + "主题", + "正文", +) +``` + +### 3. 获取短信客户端(已初始化) + +```go +// 直接获取已初始化的短信客户端 +smsClient, err := fac.GetSMSClient() +if err != nil { + log.Fatal(err) +} + +// 直接使用,无需再创建 +resp, err := smsClient.SendSimple( + []string{"13800138000"}, + map[string]string{"code": "123456"}, +) +``` + +### 4. 完整示例 + +```go +package main + +import ( + "log" + + "git.toowon.com/jimmy/go-commom/config" + "git.toowon.com/jimmy/go-commom/factory" +) + +func main() { + // 加载配置 + cfg, err := config.LoadFromFile("./config.json") + if err != nil { + log.Fatal(err) + } + + // 创建工厂 + fac := factory.NewFactory(cfg) + + // 获取邮件客户端(已初始化,可直接使用) + emailClient, err := fac.GetEmailClient() + if err != nil { + log.Printf("Email client not available: %v", err) + } else { + // 直接使用 + err = emailClient.SendSimple( + []string{"recipient@example.com"}, + "测试邮件", + "这是测试内容", + ) + if err != nil { + log.Printf("Failed to send email: %v", err) + } + } + + // 获取短信客户端(已初始化,可直接使用) + smsClient, err := fac.GetSMSClient() + if err != nil { + log.Printf("SMS client not available: %v", err) + } else { + // 直接使用 + resp, err := smsClient.SendSimple( + []string{"13800138000"}, + map[string]string{"code": "123456"}, + ) + if err != nil { + log.Printf("Failed to send SMS: %v", err) + } else { + log.Printf("SMS sent: %s", resp.RequestID) + } + } + + // 如果需要访问配置对象 + cfgObj := fac.GetConfig() + dsn, _ := cfgObj.GetDatabaseDSN() + log.Printf("Database DSN: %s", dsn) +} +``` + +## API 参考 + +### NewFactory(cfg *config.Config) *Factory + +创建工厂实例。 + +**参数:** +- `cfg`: 配置对象 + +**返回:** 工厂实例 + +### (f *Factory) GetEmailClient() (*email.Email, error) + +获取邮件客户端(已初始化)。 + +**返回:** 已初始化的邮件客户端对象和错误信息 + +**说明:** 如果邮件配置为nil,返回错误。 + +### (f *Factory) GetSMSClient() (*sms.SMS, error) + +获取短信客户端(已初始化)。 + +**返回:** 已初始化的短信客户端对象和错误信息 + +**说明:** 如果短信配置为nil,返回错误。 + +### (f *Factory) GetConfig() *config.Config + +获取配置对象。 + +**返回:** 配置对象 + +## 优势 + +### 之前的方式(需要调用方实现) + +```go +// 调用方需要自己实现创建逻辑 +cfg, _ := config.LoadFromFile("./config.json") +emailConfig := cfg.GetEmail() +if emailConfig == nil { + log.Fatal("email config is nil") +} +emailClient, err := email.NewEmail(emailConfig) +if err != nil { + log.Fatal(err) +} +// 才能使用 +emailClient.SendSimple(...) +``` + +### 使用工厂方式(直接获取已初始化对象) + +```go +// 直接获取已初始化的对象,无需重复实现 +cfg, _ := config.LoadFromFile("./config.json") +fac := factory.NewFactory(cfg) +emailClient, err := fac.GetEmailClient() +if err != nil { + log.Fatal(err) +} +// 直接使用 +emailClient.SendSimple(...) +``` + +## 注意事项 + +1. **配置检查**:工厂方法会自动检查配置是否存在,如果配置为nil会返回错误 +2. **错误处理**:所有Get方法都可能返回错误,需要正确处理 +3. **配置对象**:可以通过`GetConfig()`方法访问原始配置对象,获取其他配置信息 + +## 示例 + +完整示例请参考 `examples/factory_example.go` + diff --git a/examples/factory_example.go b/examples/factory_example.go new file mode 100644 index 0000000..dba3dec --- /dev/null +++ b/examples/factory_example.go @@ -0,0 +1,72 @@ +package main + +import ( + "fmt" + "log" + + "git.toowon.com/jimmy/go-commom/config" + "git.toowon.com/jimmy/go-commom/factory" +) + +func main() { + // 加载配置 + cfg, err := config.LoadFromFile("./config/example.json") + if err != nil { + log.Fatal("Failed to load config:", err) + } + + // 创建工厂实例 + fac := factory.NewFactory(cfg) + + // 示例1:获取邮件客户端(已初始化,可直接使用) + fmt.Println("=== Example 1: Get Email Client ===") + emailClient, err := fac.GetEmailClient() + if err != nil { + log.Printf("Email client not available: %v", err) + } else { + fmt.Println("Email client created successfully") + // 直接使用,无需再创建 + _ = emailClient // 示例中不使用,实际使用时可以直接调用方法 + // err = emailClient.SendSimple( + // []string{"recipient@example.com"}, + // "测试邮件", + // "这是测试内容", + // ) + fmt.Println("Email client is ready to use") + } + + // 示例2:获取短信客户端(已初始化,可直接使用) + fmt.Println("\n=== Example 2: Get SMS Client ===") + smsClient, err := fac.GetSMSClient() + if err != nil { + log.Printf("SMS client not available: %v", err) + } else { + fmt.Println("SMS client created successfully") + // 直接使用,无需再创建 + _ = smsClient // 示例中不使用,实际使用时可以直接调用方法 + // resp, err := smsClient.SendSimple( + // []string{"13800138000"}, + // map[string]string{"code": "123456"}, + // ) + fmt.Println("SMS client is ready to use") + } + + // 示例3:访问配置对象 + fmt.Println("\n=== Example 3: Access Config Object ===") + cfgObj := fac.GetConfig() + dsn, err := cfgObj.GetDatabaseDSN() + if err != nil { + log.Printf("Database DSN not available: %v", err) + } else { + fmt.Printf("Database DSN: %s\n", dsn) + } + + redisAddr := cfgObj.GetRedisAddr() + if redisAddr != "" { + fmt.Printf("Redis Address: %s\n", redisAddr) + } + + fmt.Println("\nNote: Factory provides initialized clients directly,") + fmt.Println("no need to implement creation logic in your code.") +} + diff --git a/factory/factory.go b/factory/factory.go new file mode 100644 index 0000000..215a2b5 --- /dev/null +++ b/factory/factory.go @@ -0,0 +1,45 @@ +package factory + +import ( + "fmt" + + "git.toowon.com/jimmy/go-commom/config" + "git.toowon.com/jimmy/go-commom/email" + "git.toowon.com/jimmy/go-commom/sms" +) + +// Factory 工厂类,用于从配置创建各种客户端对象 +type Factory struct { + cfg *config.Config +} + +// NewFactory 创建工厂实例 +func NewFactory(cfg *config.Config) *Factory { + return &Factory{ + cfg: cfg, + } +} + +// GetEmailClient 获取邮件客户端(已初始化) +// 返回已初始化的邮件客户端对象,可直接使用 +func (f *Factory) GetEmailClient() (*email.Email, error) { + if f.cfg.Email == nil { + return nil, fmt.Errorf("email config is nil") + } + return email.NewEmail(f.cfg.Email) +} + +// GetSMSClient 获取短信客户端(已初始化) +// 返回已初始化的短信客户端对象,可直接使用 +func (f *Factory) GetSMSClient() (*sms.SMS, error) { + if f.cfg.SMS == nil { + return nil, fmt.Errorf("SMS config is nil") + } + return sms.NewSMS(f.cfg.SMS) +} + +// GetConfig 获取配置对象 +func (f *Factory) GetConfig() *config.Config { + return f.cfg +} +