“单应用”的概念其实是相对于”微服务”来讲的。”微服务”项目往往单个服务逻辑比较简单,不会有过于复杂的代码设计。本文使用 Focus聚焦社区 项目作为示例,主要介绍如何使用GoFrame开发框架设计包含多个系统的”单应用”项目。在开始之前,建议您先了解一下GoFrame对于开发业务型项目的一些基础设计介绍:

本文是介绍的单应用下多系统的复杂设计,如果您对此比较感兴趣,欢迎往下阅读。如果您主要接触的微服务开发场景,可选择忽略,后续会有其他的设计文章对微服务工程这块做专门的介绍。

一、项目结构

包含多个系统的单应用目录结构会不太一样,主要由于不同的系统有不同的功能逻辑,也有相同的功能逻辑。我们需要将不同的功能逻辑充分地进行解耦,互不干扰;而相同的功能抽离出来,便于复用。还是高内聚,低耦合思想。

  1. ├── app
  2. ├── dao
  3. ├── model
  4. ├── shared
  5. └── system
  6. ├── admin
  7. └── internal
  8. └── index
  9. └── internal
  10. ├── api
  11. ├── define
  12. └── service
  13. ├── config
  14. ├── document
  15. ├── library
  16. ├── packed
  17. ├── public
  18. ├── template
  19. ├── upload
  20. ├── Dockerfile
  21. ├── go.mod
  22. └── main.go
目录/文件名称说明描述
app业务逻辑层所有的业务逻辑存放目录。
dao数据访问数据库的访问操作,仅包含最基础的数据库CURD方法。
model结构模型数据相关的实体结构定义,以及一些系统间通用的数据结构定义。

-  shared

通用逻辑多系统间可复用的、通用的service功能逻辑。
system系统模块内部可能包含多个子系统,不同子系统之间资源相互隔离。
    -  index前端页面子系统,前端页面。该名称index仅作示例。
        -  internal内部模块系统内部模块,仅供当前内部系统调用,无法在系统间共享。
          -  api业务接口当前系统内部接收/解析用户输入参数的入口/接口层
          -  define结构定义当前系统内部的输入、输出数据结构定义。
          -  service逻辑封装当前系统内部业务逻辑封装,实现特定的业务需求。
config配置管理所有的配置文件存放目录。
docker镜像文件Docker镜像相关依赖文件,脚本文件等等。
document项目文档Documentation项目文档,如: 设计文档、帮助文档等等。
library公共库包公共的功能封装包,往往不包含业务需求实现。
packed打包目录资源文件打包的Go文件存放在这里,boot包初始化时自动调用。
public静态目录仅有该目录下的文件才能对外提供静态服务访问。
template模板文件模板文件存放的目录。仅当需要使用模板引擎的场景下有用。
Dockerfile镜像描述云原生时代用于编译生成Docker镜像的描述文件。
go.mod依赖管理使用Go Module包管理的依赖描述文件。
main.go入口文件程序入口文件。

可以看到,基本的项目结构和GoFrame官方提供的基础项目结构差别不大,主要在app目录下的目录结构有一些差别。比较常见的单应用多系统是这样的:一个前台系统,一个后台系统。例如:

单应用多系统设计 - 图1

图1. 单应用多系统项目结构

二、复用模块

数据访问 - dao

可以看到处于外层的daomodel都是可被多个业务系统复用,这应该能够很好理解,这两块本身就是耦合最低的功能模块。dao模块负责数据访问管理,对于整个应用来讲,数据是通用的,可以被多个业务系统访问。

通用结构 - model

但是需要注意的是,此时的model中仅包含通用的数据结构定义,例如数据库实体对象定义、共享数据结构定义。例如,以下图例model中的captchacontextview都是共享数据结构;而其他的模块均是数据库实体数据结构封装。

单应用多系统设计 - 图2

图2. 可复用model通用数据结构模块

通用逻辑 - shared

shared模块存放的是多系统间可复用的service功能逻辑,由于service这个名称被使用到业务系统中,因此外部相同职责的模块名称尽量不要重复冲突以便更好维护,所以叫做shared。在下图的示例中,可以看到,我们整个单应用中,多个系统间共用了context上下文的功能逻辑。

单应用多系统设计 - 图3

图3. 可复用的shared功能逻辑

三、业务系统

在这个示例中,包含了两个业务系统index前台系统和admin后台系统,两个业务系统在代码设计上相互独立,没有耦合。可以看到,每个业务系统内部都使用internal包将自身的业务逻辑包含了起来,目的是使得内部的功能模块不对外公开,使得整个项目在模块引用的时候更加简洁。

单应用多系统设计 - 图4

图4. 多业务系统代码结构示例

每个业务系统下均有apidefineservice三层代码模块,每个模块均负责当前业务系统下对应的职责管理。

业务接口 - api

api模块负责当前业务系统的请求输入与输出,包括对输入参数的过滤、转换、校验,对输出数据结构的维护,并调用service实现业务逻辑处理。

结构定义 - define

define模块负责当前业务系统的数据结构定义,包括自定义的数据对象、输入输出数据结构等定义,其功能类似于GoFrame项目结构中的model,但是不包含数据库实体对象数据结构定义,而数据库实体对象数据结构定义由外层的model负责。

业务逻辑 - service

service模块负责当前业务系统的业务逻辑实现以及功能封装。

系统初始化

可以看到我们整个项目结构中,已经不存在GoFrame框架项目结构推荐的bootrouter模块。因为在多系统并存的情况下,无法执行统一的初始化和路由注册,初始化和路由注册交给各个业务系统自行维护,这样的目的也是为了尽可能地实现低耦合设计。例如,前台系统的初始化即路由注册在这里管理:

单应用多系统设计 - 图5

图5. 业务系统初始化即路由注册

四、应用初始化

应用初始化主要负责一些通用的初始化设置,并调用各个业务系统的初始化方法实现系统的初始化。随后启动应用。

单应用多系统设计 - 图6

图6. 应用初始化即启用

Content Menu