1. 目录规范

一个好的目录结构至少要满足以下几个要求。

  • 命名清晰:目录命名要清晰、简洁,不要太长,也不要太短,目录名要能清晰地表达出该目录实现的功能,并且目录名最好用单数。一方面是因为单数足以说明这个目录的功能,另一方面可以统一规范,避免单复混用的情况。
  • 功能明确:一个目录所要实现的功能应该是明确的、并且在整个项目目录中具有很高的辨识度。也就是说,当需要新增一个功能时,我们能够非常清楚地知道把这个功能放在哪个目录下。
  • 全面性:目录结构应该尽可能全面地包含研发过程中需要的功能,例如文档、脚本、源码管理、API 实现、工具、第三方包、测试、编译产物等。
  • 可预测性:项目规模一定是从小到大的,所以一个好的目录结构应该能够在项目变大时,仍然保持之前的目录结构。
  • 可扩展性:每个目录下存放了同类的功能,在项目变大时,这些目录应该可以存放更多同类功能。

根据功能,我们可以将目录结构分为结构化目录结构和平铺式目录结构两种。

GoGo
2. 平铺式目录结构
Go
loggithub.com/golang/glog
$ ls glog/
glog_file.go  glog.go  glog_test.go  LICENSE  README
3. 结构化目录结构
GoGo
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── go.mod
├── init
├── internal
├── LICENSE.md
├── Makefile
├── pkg
├── README_zh-CN.md
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website
GoGoGo

3.1 Go 应用开发目录

开发的代码包含前端代码和后端代码,可以分别存放在前端目录和后端目录中。

3.1.1 /web

前端代码存放目录,主要用来存放 Web 静态资源,服务端模板和单页应用(SPAs)。

3.1.2 /cmd

main/cmd
$ ls cmd/
gendocs  geniamdocs  genman   genyaml  apiserver iamctl  iam-pump

$ ls cmd/apiserver/
apiserver.go
/cmd/<组件名>/pkg/internal

3.1.3 /internal

/internal
internalGo
An import of a path containing the element “internal” is disallowed
if the importing code is outside the tree rooted at the parent of the
"internal" directory.
internalinternalinternal
$ ls internal/
apiserver  authzserver  iamctl  pkg  pump  watcher
/internal
/internal/apiserver/internal/pkg/internal/pkg
/internal/pkg/pkg

3.1.4 /pkg

import

3.1.5 /vendor

go mod vendorGovendor

3.1.6 /third_party

forkgo/third_party/forkedforkupstream

3.2 Go 应用测试目录

3.2.1 /test

/testGo/test/data/test/testdata
._

3.3 Go 应用部署目录

3.3.1 /configs

confdconsul-template
apiVersion: v1    
user:    
  username: ${CONFIG_USER_USERNAME} # iam 用户名    
  password: ${CONFIG_USER_PASSWORD} # iam 密码

3.3.2 /deployments

IaasPaaSKubernetesdeploy

3.3.3 /init

systemdupstartsysvrunitsupervisordsysemdunit

3.4 Go 应用项目管理目录

3.4.1 /Makefile

GoMakefileMakefile
lintgolangci-linttestgo test ./...buildCPUimage/image.pushDocker/Kubernetescleangenprotobuf pb.godeployreleaseDocker HubgithubhelpMakefileadd-copyrightswaggerswaggerAPIMakefile
makeformat -> lint -> test -> buildgen -> format -> lint -> test -> build

3.4.2 /scripts

该目录主要用来存放脚本文件,实现构建、安装、分析等不同功能。不同项目,里面可能存放不同的文件,但通常可以考虑包含以下 3 个目录:

/scripts/make-rulesmakefile/MakefileMakefile/scripts/make-rules/scripts/libshellshellshellshell/scripts/liblogging.shutil.sh/scripts/install/scripts
shelliam::log::info

3.4.3 /build

这里存放安装包和持续集成相关的文件。这个目录下有 3 个大概率会使用到的目录,在设计目录结构时可以考虑进去。

/build/packageDockerdebrpmpkg/build/ciCI/build/dockerDockerfile

3.4.4 /tools

/pkg/internal

3.4.5 /githooks

Gitcommit-msg

3.4.6 /assets

CSSJavaScript

3.4.7 /website

Github

3.5 Go 应用文档目录

3.5.1 /README.md

README

3.5.2 /docs

godoc
/docs/devel/{en-US,zh-CN}/docs/guide/{en-US,zh-CN}/docs/images

3.5.3 /CONTRIBUTING.md

CONTRIBUTING.md

3.5.4 /api

/apiAPI/api/protobuf-spec/api/thrift-spec/api/http-specopenapiswaggerAPI

3.5.5 /LICENSE

Apache 2.0MITBSDGPLMozillaLGPL

3.5.6 /CHANGELOG

CHANGELOG

3.5.7 /examples

存放应用程序或者公共包的示例代码

4. 不建议的目录

4.1 /src

其中一个重要的原因是:在默认情况下,Go 语言的项目都会被放置到$GOPATH/src 目录下。这个目录中存放着所有代码,如果我们在自己的项目中使用/src 目录,这个包的导入路径中就会出现两个 src,例如:

$GOPATH/src/github.com/marmotedu/project/src/main.go

这样的目录结构看起来非常怪。

4.2 /xxs

Go
5. 建议
cmdpkginternal
$ tree --noreport -L 2 tms
tms
├── cmd
├── internal
├── pkg
└── README.md
GitGit.keep
$ ls -A build/ci/ 
.keep

先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦