依赖注入
不使用依赖注入(不推荐)
Go
func (h *AdminHandler) Login(c *gin.Context) {
// 每次都要自己创建服务
adminService := service.NewAdminService()
userService := service.NewUserService()
taskService := service.NewTaskService()
// 使用服务
admin, err := adminService.AuthenticateAdmin(username, password)
// ...
}
使用依赖注入(推荐)
Go
// 1. 定义结构体,声明需要什么
type AdminHandler struct {
adminService *service.AdminService
userService *service.UserService
taskService *service.TaskService
}
// 2. 创建时注入依赖
func NewAdminHandler() *AdminHandler {
return &AdminHandler{
adminService: service.NewAdminService(), // 注入
userService: service.NewUserService(), // 注入
taskService: service.NewTaskService(), // 注入
}
}
// 3. 使用时直接调用
func (h *AdminHandler) Login(c *gin.Context) {
// 直接使用,不需要重新创建
admin, err := h.adminService.AuthenticateAdmin(username, password)
// ...
}
为什么用依赖注入?
问题1:重复创建
Go
// 每个方法都要创建服务
func (h *AdminHandler) Login(c *gin.Context) {
adminService := service.NewAdminService() // 重复创建
// ...
}
func (h *AdminHandler) CreateUser(c *gin.Context) {
adminService := service.NewAdminService() // 重复创建
// ...
}
解决:依赖注入
Go
// 只创建一次,所有方法共享
type AdminHandler struct {
adminService *service.AdminService // 只创建一次
}
func (h *AdminHandler) Login(c *gin.Context) {
// 直接使用
admin, err := h.adminService.AuthenticateAdmin(username, password)
}
func (h *AdminHandler) CreateUser(c *gin.Context) {
// 直接使用
user, err := h.adminService.CreateUser(username, password)
}
实例
对比其他语言
Go
Go: NewAdminHandler()
Java: new AdminHandler()
C++: new AdminHandler()
Python: AdminHandler()
实际例子
正确的命名
Go
// 结构体
type AdminHandler struct {
adminService *service.AdminService
}
// 构造函数
func NewAdminHandler() *AdminHandler {
return &AdminHandler{
adminService: service.NewAdminService(),
}
}
// 使用
handler := NewAdminHandler()
错误的命名
Go
// ❌ 错误:有空格
func New AdminHandler() *AdminHandler {
// ...
}
// ❌ 错误:小写
func newAdminHandler() *AdminHandler {
// ...
}
// ❌ 错误:其他命名
func CreateAdminHandler() *AdminHandler {
// ...
}
123