Go基础(⑦实例和依赖注入)
依赖注入
不使用依赖注入(不推荐)
func (h *AdminHandler) Login(c *gin.Context) {// 每次都要自己创建服务adminService := service.NewAdminService()userService := service.NewUserService()taskService := service.NewTaskService()// 使用服务admin, err := adminService.AuthenticateAdmin(username, password)// ...
}
使用依赖注入(推荐)
// 1. 定义结构体,声明需要什么
type AdminHandler struct {adminService *service.AdminServiceuserService *service.UserServicetaskService *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:重复创建
// 每个方法都要创建服务
func (h *AdminHandler) Login(c *gin.Context) {adminService := service.NewAdminService() // 重复创建// ...
}func (h *AdminHandler) CreateUser(c *gin.Context) {adminService := service.NewAdminService() // 重复创建// ...
}
解决:依赖注入
// 只创建一次,所有方法共享
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: NewAdminHandler()
Java: new AdminHandler()
C++: new AdminHandler()
Python: AdminHandler()
实际例子
正确的命名
// 结构体
type AdminHandler struct {adminService *service.AdminService
}// 构造函数
func NewAdminHandler() *AdminHandler {return &AdminHandler{adminService: service.NewAdminService(),}
}// 使用
handler := NewAdminHandler()
错误的命名
// ❌ 错误:有空格
func New AdminHandler() *AdminHandler {// ...
}// ❌ 错误:小写
func newAdminHandler() *AdminHandler {// ...
}// ❌ 错误:其他命名
func CreateAdminHandler() *AdminHandler {// ...
}
123