1.9. 项目组织的结构

项目组织讲究的是将项目按照功能划分,将完成相似功能的代码块组织在一起,这样便于理解项目,同时有利于项目的拓展和解耦。

1.9.1. 1.领域驱动的方式

领域驱动设计主要包括以下4部分:

应用层(Application)。

基础设施层(Infrastructure)。

领域层(Domain)。

用户界面层(UserInterface)。

(1)应用层

主要完成的任务是为程序提供任务处理,即调用抽象之后的应用。

(2)基础设施层

主要是与业务不相关的代码块的集合,比如字符串操作、数值运算、文件操作等。

(3)领域层

领域层是领域驱动设计的核心,首先需要根据项目抽象出领域内的相关概念,再在领域内相关概念的基础上完成资源的操作。

(4)用户界面层

负责向用户展现信息,并且会解析用户行为,即常说的展现层。

以设计一个RESTful API风格的项目为例,领域驱动设计的项目组织的结构大概如下:

workspace
    app
    domain
    infra
    main
    scheduler
        scheduler.go
        ui
            api-server
                api-server.go
                router_function.go
            parse
                parse

1.9.2. 2.业务驱动的方式

在日常开发过程中,编写API的业务需求应该很多,特别是选择Web方面的工作。下面这种风格的项目组织适合绝大多数Web层面的项目开发。

  • cmd:命令行功能集合。

  • configs:项目的配置文件集合。

  • deployments:构建Docker镜像等文件集合。

  • docs:文档集合。

  • initializers:初始化文件集合。

  • logs:存储项目日志文件集合。

  • pkg:项目辅助功能,比如中间件、插件等。

  • scripts:脚本文件集合。

  • src:项目的核心文件,核心的处理环节。

  • tools:项目辅助工具。

  • vendor:第三方库文件集合。

  • main.go:项目函数入口。

  • Makefile:项目构建命令集合。

后面也会以这个项目组织的结构作为参考进行项目开发。

1.9.3. 3.面向包的设计

  • 细化包目录

  • import包的最后一层,要非常明确包的主要功能

例如:
● internal/
  ○ app1/
    ■ controllers/
      ● UserController.go
      ● AdminController.go
应改为:
● internal/
  ○ app1/
    ■ controllers/
      ● usercontroller/
        ○ user.go
      ● admincontroller/
        ○ admin.go

1.9.4. 4.Go 项目结构

/cmd

本项目的主干。每个应用程序的目录名应该与你想要的可执行文件的名称相匹配,例如:

● cmd/
  ○ app1/
    ■ main.go
  ○ app2/
    ■ main.go

/internal

这个包存放本项目的包,注意放在这里的包不能被其他项目import,在build其中,go的编译器会做强制校验(1.4加入的特性),例如:

○ app1/
  ■ routes/
  ■ controllers/
  ■ services/
  ■ models/
  ■ dtos/
○ app2/
○ pkg/        这里存放app1与app2公用的包,例如response结构体,自定义的error,中间键等

/pkg

如果你把代码包放在根目录的pkg下,其他项目是可以直接导入pkg下的代码包的,即这里的代码包是开放的。一般项目不会使用到,但考虑到项目不确定性,项目初始化时,最好带上这个目录

/vendor

应用程序依赖项,执行go mod vendor 会自动生成该目录,并导入项目依赖

注意在go mod模式下,不会引入vendor下的包(导包爆红,使用 go mod tidy)

/web

前后端没分离的项目才会使用,存放前端资源

/configs

项目配置文件,例如:

● configs/
  ○ app1/
    ■ app1.toml
  ○ app2/
    ■ app2.yaml

/docs

设计文档,使用文档等

● docs/
  ○ app1/
  ○ app2

/logs

日志目录,一般情况下,该目录下的所有内容会设置为ignore,不提交到代码仓库。开发人员做测试才会使用

/test

额外的外部测试应用程序和测试数据。你可以随时根据需求构造 /test 目录。通常可以用来做demo测试,除非与项目本身完整性有直接关系,该目录下所有内容可以设置为ignore,不提交到代码仓库。

go.mod

使用go moudle做管理,执行go mod init时,自动生成

go.sum

使用go moudle做管理,执行go mod vendor或其他有pull性质命令时会自动生成