当前位置: 代码网 > it编程>前端脚本>Golang > Golang:微服务常用代码分层结构

Golang:微服务常用代码分层结构

2024年08月01日 Golang 我要评论
代码分层结构是一个老生常谈的话题,好的代码结构能够使得系统易于理解、开发及维护,如果代码结构很混乱就会使得不同层级的代码块耦合,导致难以维护和拓展。

1.代码结构

代码分层结构是一个老生常谈的话题,好的代码结构能够使得系统易于理解、开发及维护,如果代码结构很混乱就会使得不同层级的代码块耦合,导致难以维护和拓展。
比较经典的代码结构(宏观)有web的mvc模式分层结构,将代码分为controller路由层、model模型层、view视图层。
在这里插入图片描述

更加具体地来看,对于微服务来说(不考虑前后端一体化情况),后端只有controller及model层, 可以细化为:

  • controller层:路由层,定义接口的路由
  • service层:逻辑层,定义服务的逻辑
  • dao层:数据层,定义数据库间的交互
  • entity层:实体层,定义数据po、dto、vo等结构
  • utils层:工具层,定义各类工具
    在这里插入图片描述

2.golang:微服务代码分层结构

这里分享一下工作中常用到的golang微服务代码分层结构,以及每一层结构的定义及能做的事情、不能做的事情。
在这里插入图片描述

由于golang是不支持包之间循环依赖的,所以从hanlders到pkgs,均为单向依赖。下面介绍各个层级的含义,以及要做的事情。

2.1.pkg

pkg包存放与业务逻辑无关的工具包,如格式化工具、结构体转换工具等。

pkg/
 |- formatter/
  |- formatter.go
 |- converter/
  |- converter.go
  • converter.go
func obj2string(obj interface{}) (string, error) {
    bytes, err := json.marshal(&obj)
    if err != nil {
        return "", err
    }
    return string(bytes), nil
}

2.2.entity

entity包存放领域实体及其相关方法及枚举。

  • entity包只能提供最基本的和实体相关的方法,如定义了user结构体,提供isvaliduser方法判断该user是否有效等。
  • entity包不依赖于其他任何包(基础类库、pkgs包)除外,只提供最基础的领域模型定义。
entity/
 |- user.go
 |- item.go
  • user.go
type usertype string

const (
    usertypeadmin  usertype = "admin"
    usertypenormal usertype = "normal"
)

type user struct {
    usertype usertype
    userid   int64
    username string
}

func (u *user) isadmin() bool {
    return u.usertype == usertypeadmin
}

2.3.dao

dao包存放于数据库交互的所有代码,即数据的增、删、改、查。

  • dao包包含领域模型的所有数据crud操作
  • dao包不包含业务逻辑相关的操作
dao/
 |- dao.go
 |- user_dao.go
  • dao.go
var userdao userdaoif

func initdao() {
    userdao = new(userdao)
}
  • user_dao.go
type userdaoif interface {
    getuser(userid int64) (*entity.user, error)
    createuser(user *entity.user) error
}

type userdao struct{}

// createuser implements userdaoif
func (*userdao) createuser(user *entity.user) error {
    panic("unimplemented")
}

// getuser implements userdaoif
func (*userdao) getuser(userid int64) (*entity.user, error) {
    panic("unimplemented")
}

2.4.policies

policies包存放和业务逻辑校验、实体验证相关的代码。

policies/
 |- policy.go
 |- user_policy.go
  • policy.go
var userpolicy userpolicyif

func init() {
    userpolicy = new(userpolicy)
}
- user_policy.go
type userpolicyif interface {
    canlogin(userid int64) bool
    canregister(userid int64) bool
}

type userpolicy struct{}

// canlogin implements userpolicyif
func (*userpolicy) canlogin(userid int64) bool {
    panic("unimplemented")
}

// canregister implements userpolicyif
func (*userpolicy) canregister(userid int64) bool {
    panic("unimplemented")
}

2.5.services

services存放业务逻辑相关代码,是整个项目中逻辑最复杂的部分。

services/
 |- service.go
 |- user/
  |- user_service.go    
 |- item/
  |- item_service.go
  • service.go
var userservice userserviceif

func init() {
    userservice = new(userservice)
}
- user_service.go
type userserviceif interface {
    userlogin(u *entity.user) error
}

type userservice struct{}

// userlogin implements userserviceif
func (*userservice) userlogin(u *entity.user) error {
    panic("unimplemented")
}

2.6.handlers

handlers定义了各类对外处理器入口,如http、rpc、eventbus等处理器。

  • handlers中的处理器只做三件事情:接受请求解析入参、调用services完成业务逻辑、构造响应参数
  • handlers不包含业务代码逻辑,应该简单地作路由使用
handlers/
 |- handler.go
 |- rpc/
  |- user_rpc.go    
 |- http/
  |- item_http.go

2.7.其他包

  • conf包:存放相关的配置文件,如config_prod.yaml等
  • script包:存放系统相关的脚本,如编译脚本build.sh等
  • cmd包:存放相关的可直接运行的go脚本,如刷数脚本reflush.go等
(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com