跳到主要内容

Go 面向接口和依赖注入的编写逻辑

· 阅读需 3 分钟
素明诚
Full stack development

已完成一个消息通知系统为例,这里自上而下的思考步骤如下

明确系统目标和功能

目标:创建一个灵活的通知系统,能够通过不同的方式(如电子邮件和短信等)发送通知。

功能:系统应支持发送通知、管理配置、选择消息发送方式等。

确定主要组件

main:入口点,负责配置和启动服务。

NotificationService:负责发送通知的核心逻辑。

MessageSender 接口及其实现:定义和实现不同的消息发送方式(如 EmailSenderSmsSender)。

Config 结构体:管理和存储配置信息。

定义核心接口

确定 MessageSender 接口,它应该包含 Send(message string) error 方法。这个接口为后续具体实现提供了基础。

实现具体功能

开始实现具体的功能模块

配置管理:创建 Config 结构体和相应的方法来读取和管理配置信息。

消息发送实现:实现 EmailSenderSmsSender,确保它们符合 MessageSender 接口。

通知服务:实现 NotificationService,该服务使用 MessageSender 接口进行通知发送。

实现主程序逻辑

main 函数中,根据配置选择消息发送者,创建 NotificationService 实例,并调用发送通知的方法。

实现

main.go

package main

import (
"log"
)

func main() {
// 配置管理
config := Config{NotificationType: "email"} // 可以改为 "sms"

// 根据配置创建消息发送者
sender, err := CreateMessageSender(config)
if err != nil {
log.Fatalf("Error creating message sender: %v", err)
}

// 创建通知服务实例
notificationService := NewNotificationService(sender)

// 发送通知
if err := notificationService.Notify("Hello via Notification Service"); err != nil {
log.Fatalf("Error sending notification: %v", err)
}

// 发送空消息,触发错误
if err := notificationService.Notify(""); err != nil {
log.Printf("Expected error: %v", err)
}
}

config.go

package main

// Config 用于管理配置信息
type Config struct {
NotificationType string
}

message_sender.go

package main

import "errors"

// MessageSender 是一个接口,定义了发送消息的方法
type MessageSender interface {
Send(message string) error
}

// CreateMessageSender 根据配置创建对应的 MessageSender 实现
func CreateMessageSender(config Config) (MessageSender, error) {
switch config.NotificationType {
case "email":
return &EmailSender{}, nil
case "sms":
return &SmsSender{}, nil
default:
return nil, errors.New("unsupported notification type")
}
}

notification_service.go

package main

import (
"errors"
)

// NotificationService 是一个结构体,包含了一个 MessageSender 类型的字段 sender
type NotificationService struct {
sender MessageSender
}

// NewNotificationService 是一个构造函数,用于创建 NotificationService 实例
func NewNotificationService(sender MessageSender) *NotificationService {
return &NotificationService{sender: sender}
}

// Notify 是 NotificationService 结构体的一个方法,用于发送通知
func (n *NotificationService) Notify(message string) error {
if message == "" {
return errors.New("message cannot be empty")
}
return n.sender.Send(message)
}

senders.go

package main

import (
"log"
)

// EmailSender 发送电子邮件
type EmailSender struct{}

// Send 实现了 MessageSender 接口
func (e *EmailSender) Send(message string) error {
// 模拟发送电子邮件的逻辑
log.Printf("Sending email: %s", message)
return nil // 假设发送成功
}

// SmsSender 发送短信
type SmsSender struct{}

// Send 实现了 MessageSender 接口
func (s *SmsSender) Send(message string) error {
// 模拟发送短信的逻辑
log.Printf("Sending SMS: %s", message)
return nil // 假设发送成功
}