V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Cola98
V2EX  ›  程序员

关于自己对 Go web 的包结构理解

  •  
  •   Cola98 · 2022-07-11 07:58:32 +08:00 · 3757 次点击
    这是一个创建于 870 天前的主题,其中的信息可能已经有所发展或是发生改变。

    不同语言的项目结构都不太一样的,就像 MVC 并不是 Java 的专属,但是现在提到 MVC 大家都会提到 Java ,从而到 spring/spring Boot 。

    这里推荐一个项目结构,它并不是 golang 官方的标准,再加上阿里的 Java 开发手册,如下所示:

    • cmd: 主要是各种功能的入口,简单来说像 main.go 就可以放到这里。
    • internal(内包是不希望其他人在其应用程序或库中导入代码)
      • db: 数据库相关的配置。
      • dao: 和数据库交互的都可以放在这里,我把 CRUD 之类的都放在这里了。
      • model: 和数据库表对应。
      • service: 具体逻辑实现。
      • dto: 放一些和前端交互的参数
      • controller: 做一些校验。
    • pkg: 外部应用程序可以使用的库代码,其他项目会导入这些库。
    • vendor: 这里就根据版本来了,一些老的 golang 项目还会有,存放一些第三方库,到后来 go mod 的出现这个就不需要有了。

    像 internal 这种就可以根据自己的需求来,我是参考了阿里的 Java 开发手册还有之前在上海实习的时候的项目结构。

    这是我写的博客中一部分,附上博客链接( https://shuimo03.github.io/)

    27 条回复    2022-07-11 19:14:29 +08:00
    cooper
        1
    cooper  
       2022-07-11 08:03:25 +08:00   ❤️ 1
    挺好,建议 controller 改为 handle 。
    ychost
        2
    ychost  
       2022-07-11 08:03:43 +08:00   ❤️ 1
    GO 就不要搞 Java 的结构了,太啰嗦
    Cola98
        3
    Cola98  
    OP
       2022-07-11 08:31:49 +08:00
    @cooper 嗯嗯,之前主要是习惯了
    Cola98
        4
    Cola98  
    OP
       2022-07-11 08:32:45 +08:00
    @ychost 嗯嗯,也是参考了一些别的项目,发现像 Java 的比较多一点,但是这样写起来心智负担比较大
    charmToby
        5
    charmToby  
       2022-07-11 09:09:41 +08:00   ❤️ 2
    model 和 dao 层我感觉可以放一起
    fiypig
        6
    fiypig  
       2022-07-11 09:10:14 +08:00   ❤️ 1
    db 可以改成 config 因为不单单是 db, 其实 go 最方便就是自己造,随便弄,过于约束也很麻烦
    panlatent
        7
    panlatent  
       2022-07-11 09:12:30 +08:00   ❤️ 1
    赞同 #2 的,目录结构多花心思搞 多设计下没毛病,但是类似 Java 之类的结构,拿到了 Go 是真的水土不服。
    dacapoday
        8
    dacapoday  
       2022-07-11 09:27:59 +08:00   ❤️ 1
    如果是小型 web 程序,这种结构太沉重了。java 是历史原因导致的,但 go 没有这种包袱。
    dacapoday
        9
    dacapoday  
       2022-07-11 09:30:49 +08:00
    @dacapoday go 的关键词比较少,表达能力不如 java ,采用 java 的这种结构会多很多代码。让 go 的开发效率像 java 一样低效,费人力。
    sadfQED2
        10
    sadfQED2  
       2022-07-11 09:31:28 +08:00 via Android   ❤️ 1
    dao 和 model 可以合成一个,两个比较冗余,但问题也不大

    controller 和 service 中间还应该加一层,因为 service 之间不能互调,互调的业务逻辑放到 controller 中也不合适
    zhangzEric
        11
    zhangzEric  
       2022-07-11 09:35:11 +08:00   ❤️ 1
    OP 博客里很多没完成的文章啊,本来抱着探索的希望进去,好几篇都是写一半空一半,建议 OP 后续有空填一下坑😂
    coolair
        12
    coolair  
       2022-07-11 10:02:47 +08:00   ❤️ 1
    这种结构真没必要用 Go 了,直接用 Java 不香吗?
    qW7bo2FbzbC0
        13
    qW7bo2FbzbC0  
       2022-07-11 10:06:58 +08:00
    - adapter
    - model
    - controller
    - service/repository
    - helper
    sciel
        14
    sciel  
       2022-07-11 10:12:37 +08:00 via iPhone   ❤️ 1
    /
    ├── api
    ├── internal
    │ ├── cmd 入口指令
    │ ├── consts
    │ ├── controller
    │ ├── dao
    │ ├── model
    │ └── service
    ├── manifest 配置文件
    ├── resource
    ├── utility 通用工具
    ├── go.mod
    └── main.go

    我觉得这个就挺好,来自 goframe
    LoNeFong
        15
    LoNeFong  
       2022-07-11 10:32:49 +08:00
    keepeye
        16
    keepeye  
       2022-07-11 11:15:45 +08:00   ❤️ 1
    goframe 的分层设计可以参考一下
    freakxx
        17
    freakxx  
       2022-07-11 12:11:08 +08:00
    @sadfQED2 #10

    这个其实是我一大难受的地方,不知有没比较好的处理方式。

    比如
    A service 需要 调用 B service 的某一个 func
    B service 反过来可能需要用到 B service 的 func

    抛上一层后,还是解决不了循环引用的问题,总感觉不够直觉性。
    然后这里就会开始变得有点脏,要么是冗余,要么就是需要做一些繁琐的处理。
    sadfQED2
        18
    sadfQED2  
       2022-07-11 12:16:52 +08:00 via Android
    @freakxx #17

    所以 controller 和 service 之间应该加一个业务逻辑层呀,专门用来调多个 service
    blless
        19
    blless  
       2022-07-11 14:52:23 +08:00
    要我说不如 DDD 。写到很多复杂业务的时候,无脑 controller 其实发现很多代码不知道放哪里,最后又都放到 controller 里,分了其实最后也没怎么分。DDD 从开始会让你拆分业务领域,持久层跟表现层其实都不是业务的重点。
    freakxx
        20
    freakxx  
       2022-07-11 14:58:33 +08:00
    @sadfQED2 #18
    是这么说,但就像#19 说的,业务代码膨胀后,代码有时会有些不知放哪,挺烦恼的事情
    gowk
        21
    gowk  
       2022-07-11 17:23:45 +08:00
    @blless #19
    我敢说国内 90%的团队是玩不转 DDD 的,因为好多连基本的面向对象都写不好,更别提 DDD 了。
    理想跟现实还是有很大差距的,就像 RESTFul API 其实是需要很好的设计去支撑的,不然到就是给自己找麻烦。
    最后发现还不如 GET/POST 一把梭
    dcsuibian
        22
    dcsuibian  
       2022-07-11 18:03:01 +08:00   ❤️ 1
    这种结构不属于 Java 的“包袱”而是财富,Java 根本没有规定要这么处理。
    搞成这样的本质原因是大部分人根本不知道怎么设计一个项目的代码结构,目前的结构是优胜劣汰下来的、有成功经历、受到广泛认可的,统一的设计也促进了 Java 生态圈的发展。

    但这种结构确实不适合直接拿到别的语言里,只能拿来参考。之前接触 nodejs 、python 后端的时候,按 Java 的方式写会怪怪的,不按它的写又不知道怎么组织,很头疼。
    humpy
        23
    humpy  
       2022-07-11 18:03:14 +08:00
    @blless #19 赞同,现在这种把 controller 放一块、model 放一块的组织形式,就像是公司里把所有后端放一个组、前端放一个组、产品放一个组一样,很不内聚。
    Cola98
        24
    Cola98  
    OP
       2022-07-11 19:09:43 +08:00
    @charmToby 之前有想过这样,但是感觉怪怪的,表和操作写在一起了
    Cola98
        25
    Cola98  
    OP
       2022-07-11 19:13:00 +08:00
    @panlatent
    @dcsuibian
    @dacapoday
    @coolair

    关于 Java 这个,确实直接搬运过来写 Go 会特别痛苦,所以之前也有考虑过是不是直接换成 Java 写算了,后期的话可能还会在修改一下。
    Cola98
        26
    Cola98  
    OP
       2022-07-11 19:13:40 +08:00
    感谢各位大佬给出的建议和回答,小弟下个版本在修改修改!!
    Cola98
        27
    Cola98  
    OP
       2022-07-11 19:14:29 +08:00
    @zhangzEric 后期会给补全的,有哪些感兴趣的,我优先补全,谢谢啦
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5507 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 38ms · UTC 08:49 · PVG 16:49 · LAX 00:49 · JFK 03:49
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.