前言
随着项目的代码量在不断地增长,不同的开发人员按自己意愿随意布局和创建目录结构,项目维护性就很差,代码也非常凌乱。良好的目录与文件结构十分重要,尤其是团队合作的时候,良好的目录与文件结构可以减少很多不必要的麻烦。项目目录结构规范的的本质是提高了代码的可读性,最终目的是提高团队协作效率,降低工程维护成本。
我们知道 java 项目结构是请求达到路由层控制器 controller,然后 controller 会去调用 service 层逻辑代码,然后 service 层会去调用 dao 层的接口方法,其实 dao 层都是以接口的形式提供,然后这些接口里头的都是操作数据库的方法,然后与 dao 层对应着的有一个 mapper,mapper 是以 xml 形式提供的,与 dao 层中的接口相对应,xml 中实际就是实现了 dao 接口中的这些具体方法,xml 中会与指定的 dao 接口中指定的方法进行绑定,xml 中会去写 sql 逻辑。具体请看架构师技能1:Java工程规范、浅析领域模型VO、DTO、DO、PO、优秀命名
一、Go语言自身项目的基本结构
Go项目的项目结构自1.0版本发布以来一直十分稳定,直到现在Go项目的顶层结构基本没有大的改变。go项目大致结构如下,GitHub – golang/go: The Go programming language
$ tree -LF 1 ~/go/src/github.com/golang/go
./go
├── api/
├── doc/
├── lib/
├── misc/
├── src/├── test
作为Go语言的“创世项目”,其项目结构的布局对后续的其他Go语言项目具有重要的参考意义,尤其是早期Go项目中src目录下面的结构,更是在后续被Go社区作为Go应用项目结构的模板被广泛使用。我们以早期的Go 1.3版本的src目录下的结构为例:
$ tree -LF 1 ./src
./src
├── all.bash*
├── all.bat
├── all.rc*
├── clean.bash*
├── clean.bat
├── clean.rc*
├── cmd/
├── lib9/
├── libbio/
├── liblink/
├── make.bash*
├── make.bat
├── Make.dist
├── make.rc*
├── nacltest.bash*
├── pkg/
├── race.bash*
├── race.bat
├── run.bash*
├── run.bat
├── run.rc*
└── sudo.bash*
src目录下面的结构三个特点:
2)src下的二级目录cmd下面存放着go工具链相关的可执行文件(比如:go、gofmt等)的主目录以及它们的main包源文件;
3)src下的二级目录pkg下面存放着上面cmd下各工具链程序依赖的包、go运行时以及go标准库的源文件
在Go 1.3版本以后至今,Go项目下的src目录中发生了几次结构上的变动:
Go 1.4版本中删除了Go源码树中src/pkg/xxx中pkg这一层级目录而直接使用src/xxx;
Go 1.4版本在src下面增加internal目录,用于存放无法被外部导入仅Go项目自用的包;
Go 1.6版本在src下面增加vendor目录,但Go项目自身真正启用vendor机制是在Go 1.7版本中。vendor目录中存放了go项目自身对外部项目的依赖,主要是golang.org/x下的各个包,包括:net、text、crypto等。该目录下的包会在每次Go版本发布时做更新;
Go 1.13版本在src下面增加了go.mod和go.num,实现了go项目自身的go module迁移,go项目内所有包被放入名为std的module下面,其依赖的包依然是golang.org/x下的各个包
// Go 1.13版本go项目src下面的go.mod
module std
go 1.12
require (
golang.org/x/crypto v0.0.0-20200124225646-8b5121be2f68
golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7
golang.org/x/sys v0.0.0-20190529130038-5219a1e1c5f8 // indirect
golang.org/x/text v0.3.2 // indirect
)
下面是最新的Go 1.16版本src目录下的完整布局:
├── Make.dist
├── README.vendor
├── all.bash*
├── all.bat
├── all.rc*
├── bootstrap.bash*
├── buildall.bash*
├── clean.bash*
├── clean.bat
├── clean.rc*
├── cmd/
├── cmp.bash
├── go.mod
├── go.sum
├── internal/
├── make.bash*
├── make.bat
├── make.rc*
├── race.bash*
├── race.bat
├── run.bash*
├── run.bat
├── run.rc*
├── testdata/
…
└── vendor/
Go 1.14 Go Modules 投入使用后,就无需担心 $GOPATH 以及项目放置的位置。所以项目的 vendor 可以忽略了,建议直接使用 module 来管理依赖
二、优秀开源 的go项目结构样例
1、Docker
├── cmd // 存放可执行程序,main 包放这个目录中
├── contrib // 存放一些有用的脚本或文件,但不是项目的核心部分
├── pkg // 本项目以及其他项目可以使用的包(公有)
2、Kubernetes
https://github.com/kubernetes/kubernetes
├── api
├── cmd
├── docs
├── pkg
├── plugin
├── third_party // 经过修改的第三方的代码
3、Gogs
├── cmd
├── pkg
├── public // 静态公共资源,实际项目会将其存入 CDN
总体上这些优秀开源项目,没有统一一致的目录结构方式,但大体上,有一些通用的地方,这就有
project-layout/README_zh.md at master · golang-standards/project-layout · GitHub做参考。
三、通用项目目录结构参考
参考:
project-layout/README_zh.md at master · golang-standards/project-layout · GitHub
1、web服务应用程序目录
/api
OpenAPI/Swagger 规范,JSON 模式文件,协议定义文件。
/web
特定于 Web 应用程序的组件:静态 Web 资产、服务器端模板和 SPAs。
2、通用应用目录
/configs
将你的 confd
或 consul-template
模板文件放在这里。
/init
System init(systemd,upstart,sysv)和 process manager/supervisor(runit,supervisor)配置。
/scripts
这些脚本保持了根级别的 Makefile 变得小而简单(例如, terraform/Makefile at main · hashicorp/terraform · GitHub )。
/build
将你的云( AMI )、容器( Docker )、操作系统( deb、rpm、pkg )包配置和脚本放在 /build/package
目录下。
将你的 CI (travis、circle、drone)配置和脚本放在 /build/ci
目录中。请注意,有些 CI 工具(例如 Travis CI)对配置文件的位置非常挑剔。尝试将配置文件放在 /build/ci
目录中,将它们链接到 CI 工具期望它们的位置(如果可能的话)。
/deployments
IaaS、PaaS、系统和容器编排部署配置和模板(docker–compose、kubernetes/helm、mesos、terraform、bosh)。注意,在一些存储库中(特别是使用 kubernetes 部署的应用程序),这个目录被称为 /deploy
。
/test
额外的外部测试应用程序和测试数据。你可以随时根据需求构造 /test
目录。对于较大的项目,有一个数据子目录是有意义的。例如,你可以使用 /test/data
或 /test/testdata
(如果你需要忽略目录中的内容)。请注意,Go 还会忽略以“.”或“_”开头的目录或文件,因此在如何命名测试数据目录方面有更大的灵活性。
我们可以参考project-layout/README_zh.md at master · golang-standards/project-layout · GitHub
3、其他目录
/docs
/tools
这个项目的支持工具。注意,这些工具可以从 /pkg
和 /internal
目录导入代码。
/examples
/third_party
外部辅助工具,分叉代码和其他第三方工具(例如 Swagger UI)。
/githooks
/assets
/website
如果你不使用 Github 页面,则在这里放置项目的网站数据。
4、不应该拥有的目录
/src
有些 Go 项目确实有一个 src
文件夹,但这通常发生在开发人员有 Java 背景,在那里它是一种常见的模式。如果可以的话,尽量不要采用这种 Java 模式。你真的不希望你的 Go 代码或 Go 项目看起来像 Java:-)
不要将项目级别 src
目录与 Go 用于其工作空间的 src
目录(如 How to Write Go Code 中所述)混淆。$GOPATH
环境变量指向你的(当前)工作空间(默认情况下,它指向非 windows 系统上的 $HOME/go
)。这个工作空间包括顶层 /pkg
, /bin
和 /src
目录。你的实际项目最终是 /src
下的一个子目录,因此,如果你的项目中有 /src
目录,那么项目路径将是这样的: /some/path/to/workspace/src/your_project/src/your_code.go
。注意,在 Go 1.11 中,可以将项目放在 GOPATH
之外,但这并不意味着使用这种布局模式是一个好主意。
四、代码架构
我们在《架构设计1:谈谈架构》已经提到代码架构,主要定义内容:
一、代码单元:
1、配置设计
2、框架、类库。
二、代码单元组织:
1、编码规范,编码的惯例。
2、项目模块划分
3、顶层文件结构设计,比如mvc设计。
4、依赖关系
1、代码分层和依赖
代码分层,让不同层次的代码做不同的动作。层次清晰的代码,提高可读性,从代码结构就大概能了解到代码是如何分层,每层大概功能是什么。例如java常用的Controller、Service、Mapper/Dao三层代码结构,其各层的代码逻辑范围。
2、默认上层依赖于下层
依赖规则规定上层的代码可以依赖下层,但是下层的代码不可以依赖上层。也就是说下层逻辑不可以依赖任何上层定义的变量,函数,结构体,类,模块等等代码实体。
数据层:负责数据的存储和访问
假如说,最上层应用层处使用了 go 语言的 gorm 三方库,并定义了 gorm 相关的数据库结构体及其 tag 等。那么下层数据层不可以引用任何外层中 gorm 相关的结构体或方法,甚至不应该感知到 gorm 的存在。
但是,分层架构也有一些挑战:①必须合理规划层次边界和接口;②禁止跨层次的调用及逆向用。 《架构设计5:架构模式-分层模式》 《架构设计5:架构模式-分层模式》 《架构设计5:架构模式-分层模式》
3、参考的项目目录结构
可以参考,可以根据自己团队和实际项目来做改动,规范的最主要目的是统一认知。
├── app/application // App层,处理Adapter层适配过后与框架、协议等无关的业务逻辑
├ ├── api 处理OpenAPI 接口请求
├ ├── web 请求Web页面请求
├ ├── consumer //(可选)处理外部消息
├ ├── scheduler/task //处理定时任务,比如Cron格式的定时Job
├── domain // Domain层,最纯粹的业务实体及其规则的抽象定义
│ ├── interface/gateway // 领域网关,model的核心逻辑以Interface形式在此定义,交由biz层去实现
│ └── model // 领域模型实体
├── biz/module 业务/业务模块层
├ └──module1
├ ├──dao 数据库层
├ ├──model 业务模型
├ ├──entity 数据库模型
├ ├──service 业务逻辑
├ └──manager 复用逻辑
├── configs 配置
├── init //系统初始化
├── pkg
├── public // 静态公共资源,实际项目会将其存入 CDN
├── build 打包和持续集成
├── scripts // 脚本文件:执行各种构建、安装、分析等操作的脚本
├── test // 单元测试之外的测试程序、测试数据
├── plugin 各种插件
├── util/tools 工具包
├── main.go 项目运行入口
└── pkg // 各层可共享的公共组件代码
原文地址:https://blog.csdn.net/hguisu/article/details/129342554
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_33378.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!