暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Golang 开发最佳实践

138

借鉴了 DDD(领域驱动设计) 和 分层架构(Layered Architecture),在 Java/Spring 世界里用得很多,在 Go 里虽然倾向于简化,但在中大型项目里还是非常有价值的。 Golang 开发最佳实践中常见的 分层概念,即:

  • Controller(控制层)

  • Service(服务层 业务逻辑层)

  • Repository/DAO(数据访问层,通常也包括 Mapping)

  • DTO(Data Transfer Object,数据传输对象)

  • VO(Value Object,值对象 视图对象)

  • Mapping(对象映射,通常是 DTO/VO 与实体之间的转换)

这些概念主要下面我详细展开:


1. Controller(控制层)

  • 作用:接收客户端请求,调用业务逻辑(Service),返回结果。

  • 特点

    • 负责处理 HTTP 请求(通常结合 Gin、Echo 等框架)。

    • 只做 请求解析调用 service返回响应,不写业务逻辑。

    • 输入通常是 DTO
      ,输出通常是 VO
       或 JSON Response

  • 示例

      func(c *UserController) Register(ctx *gin.Context) {
      var req dto.RegisterRequest
      if err := ctx.ShouldBindJSON(&req); err != nil
       {
              ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
      return
          }
          user, err := c.userService.Register(req)
      if err != nil
       {
              ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
      return
          }
          ctx.JSON(http.StatusOK, vo.UserVOFromEntity(user))
      }

    2. Service(服务层 业务逻辑层

    • 作用:封装业务逻辑,是核心。

    • 特点

      • 处理 业务规则(如注册时校验手机号是否存在、发送验证码、保存数据库)。

      • 调用 Repository/DAO 进行数据库操作。

      • 输入是 DTO
         或 Entity
        ,输出通常是 Entity

    • 示例

        func(s *UserService) Register(req dto.RegisterRequest) (*entity.User, error) {
        // 校验是否已存在
        if s.userRepo.ExistsByEmail(req.Email) {
        return nil, errors.New("用户已存在")
            }
            user := entity.User{
                Email:    req.Email,
                Phone:    req.Phone,
                Nickname: req.Nickname,
            }
        if err := s.userRepo.Save(&user); err != nil {
        return nil, err
            }
        return &user, nil
        }

      3. Repository DAO(数据访问层,含 Mapping)

      • 作用:封装数据库操作。

      • 特点

        • 与数据库打交道(GORM、SQL、MongoDB 等)。

        • 提供接口,如 FindByID
          Save
          Delete

        • 与业务逻辑解耦,方便切换存储方式。

      • 示例

          type UserRepository interface
           {
              Save(user *entity.User) error
              FindByID(id uint) (*entity.User, error)
              ExistsByEmail(email stringbool
          }

        4. DTO(Data Transfer Object,数据传输对象)

        • 作用请求体/传输数据

        • 特点

          • 用来接收前端请求的数据。

          • 通常与前端交互,不直接使用 Entity
            ,避免暴露数据库字段。

          • 可以带有校验标签(如 binding:"required,email"
            )。

        • 示例

            type RegisterRequest struct
             {
                Email   string `json:"email" binding:"required,email"`
                Phone    string`json:"phone" binding:"required"`
                Nickname string`json:"nickname" binding:"required"`
            }

          5. VO(Value Object / View Object,值对象 / 视图对象)

          • 作用返回给前端的对象

          • 特点

            • 与前端展示需求对应。

            • 不等于 Entity
              ,比如密码字段需要去掉,时间格式需要转成字符串。

          • 示例

              type UserVO struct
               {
                  ID       uint `json:"id"`
                  Email    string `json:"email"`
                  Nickname string `json:"nickname"`
                  JoinedAt string `json:"joined_at"`
              }
              func UserVOFromEntity (u *entity.User) UserVO {
              return UserVO{
                      ID:       u.ID,
                      Email:    u.Email,
                      Nickname: u.Nickname,
                      JoinedAt: u.CreatedAt.Format("2006-01-02 15:04:05"),
                  }
              }


            6. Mapping(对象映射)

            • 作用Entity <-> DTO <-> VO 的转换

            • 特点

              • 避免 Controller/Service 层写一堆赋值代码。

              • 可以用工具(如 jinzhu/copier)简化。

            • 示例

                func(req *RegisterRequest) ToEntity() entity.User {
                return entity.User{
                        Email:    req.Email,
                        Phone:    req.Phone,
                        Nickname: req.Nickname,
                    }
                }

              推荐的目录结构

              一个比较清晰的 Golang 分层目录 可以这样组织:

                /project
                  /controller     
                // 控制器
                      user_controller.go
                  /service        
                // 业务逻辑
                      user_service.go
                  /repository     
                // 数据访问
                      user_repository.go
                  /entity         
                // 数据库实体
                      user.go
                  /dto            
                // 数据传输对象
                      register_request.go
                  /vo             
                // 视图对象
                      user_vo.go
                  /mapping        
                // 对象映射
                      user_mapping.go





                ✅ 总结

                • Controller:接收请求,调用 Service,返回响应。

                • Service:业务逻辑核心。

                • Repository:封装数据库访问。

                • DTO:请求数据对象。

                • VO:响应数据对象。

                • Mapping:DTO ↔ Entity ↔ VO 的转换工具。

                这样分层的好处是:职责清晰、易于扩展、方便测试和维护


                文章转载自数据库平台优化,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                评论