【问题标题】:Golang code organization for multi-platform multi-language project多平台多语言项目的 Golang 代码组织
【发布时间】:2014-03-04 03:20:39
【问题描述】:

我正在为一个包含多个用 Go 编写的组件的多平台项目寻找一个好的项目组织。我知道http://golang.org/doc/code.html 推荐的布局,但那里建议的布局似乎不符合我的要求。

项目组成部分是:

  • 服务器(用 Go 编写)
  • 客户端,跨平台(Go)
  • 库,在服务器和客户端之间共享 (Go)
  • 更多客户端(iOS、Android)

我的要求是:

  • 单个 git 存储库中的所有组件
  • 保持组件分离(例如,每个组件一个目录)
  • Go 组件可以构造成多个子包

我目前的做法:

project/ (this is the repository root)
  server/
    server.go (package main)
    src/          
      server/
        package1/
          package1.go
        ...
  client/
    client.go (package main)
    src/
      client/
        package2/
          package2.go
        ...
  lib/
    src/
      lib/
         lib.go
         ...
  client-ios/
    ...
  client-android/
    ...

为了构建,我使用了一个 Makefile

  1. 将 lib/ 复制到服务器/和客户端/中
  2. 分别构建server/和client/,每次设置GOPATH到各自的目录。

它可以工作,但感觉很笨拙,并且与推荐的代码布局完全不同。

这是我正在考虑的替代方案:

project/ (this is the repository root)
  gospace/
    src/
      server/...
      client/...
      lib/...
  client-ios/
    ...
  client-android/
    ...

使用这种布局,我有一个 GOPATH (gospace/),不需要笨拙的 Makefile。但是,组件并没有像第一个替代方案那样整齐地分开(即通过顶级目录)。

我的问题:哪种项目布局最适合我的需求以及 Go 约定和工具支持?有没有更好的选择?

【问题讨论】:

  • 为什么不$GOPATH/src/gospace/{server,client,lib,ios,android}。典型的 GOPATH 结构是 $GOPATH/{src,bin,pkg}。通过这种方式,您可以轻松地在 GOPATH 上的任何位置发送 go build gospace/servergospace/client
  • 这是一个不错的选择,因为它将所有组件放在同一级别。将 ios 和 android 放在 Go 工作区的 src 目录下感觉有点奇怪。 ios 和 android 有自己的子目录结构,有自己的 src 目录等,与 Go 无关。
  • 你可以在 GOPATH 下签出你的仓库(路径类似于 GOPATH/src/project/{gospace,client-ios,client-android})。由于 go 在您要求他这样做之前不会接触 client-* 目录,因此它们将愉快地一起生活在该目录中。作为奖励,您的项目将变为go getable。

标签: go organization code-organization project-organization


【解决方案1】:

这就是我组织一个类似项目的方式:

$GOPATH/src/project-root/
    lib.go
    lib_test.go

    server/
        server.go
        server_test.go

        main/
            server.go // package main; import "project-root/server"

    client/
        client.go
        client_test.go

        main/
            client.go //package main; import "project-root/client"

    client-ios/
        ....

    client-android/
        ....

虽然 server/server.goclient/client.go 大部分情况下 package main 应该可以工作,但最好将它们分开,这样您就可以将客户端/服务器嵌入到其他项目中。

【讨论】:

    【解决方案2】:

    这个问题已经很久没有回答了(关于 OP 的最后评论是 2014 年 2 月 12 日,最新的答案是 2014 年 4 月 16 日)。那时我并不了解 Go 的状态,只是在 2018/19 年才真正了解它,但看起来发生了很多变化。

    我相信,影响这篇文章答案的最大变化是 Go Modules。

    我有一个类似的项目正在进行中(Go 服务器、Go CLI、Android 应用程序、iOS 应用程序)。我目前正在使用 go 版本 go1.13.7 darwin/amd64。这是我通过 Go Modules 得到的结构(非常受 this post by Ben Johnson 的影响):

    directory-outside-GOPATH/
        go.mod
        go.sum
        domaintypes.go
        cmd/
            api/
                main.go
            cli/
                main.go
        postgres/
            ...(library Go code)...
        http/
            ...(library Go code)...
        android/
            ...(Android app)...
        iOS/
            ...(iOS app)...
        ...(other Go code).../
            ...
    

    根目录位于 GOPATH 之外,包含必要的 go.modgo.sum 文件。 domaintypes.go 文件是为了说明我留在根目录中的唯一 Go 文件是永远不会导入任何其他内容的代码 - 例如定义您的域类型/模型/服务接口/等。我个人有多个:user.gogroup.go等。

    postgreshttp 目录是我编写的库,它们都是分层适配器。每个库目录都应与其域隔离。例如HTTP 路由不应直接与数据库连接交互。

    cmd 目录是所有可执行 Go 代码所在的位置。我想要一个 API 服务器和一个单独的 CLI,所以这就是它所在的地方。这些文件应该保持相对较小,并调用您编写的所有其他库。

    至于非 Go 代码,我只是在根目录中为 Android 和 iOS 创建了单独的目录。

    【讨论】:

      猜你喜欢
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-02
      • 2015-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多