V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
mzmxcvbn
V2EX  ›  Go 编程语言

新手提问: gin+gorm 中大型项目分层问题

  •  
  •   mzmxcvbn · 2020-09-04 16:15:31 +08:00 · 7436 次点击
    这是一个创建于 1570 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近在看 gin,感觉对中大型项目的结构规划有点模糊。
    在 github 上看了一些例子,按我现在的理解分层:

    controller -- 请求入口,参数校验,调用 server,返回错误或响应
    server -- 接收已验证参数,实现具体业务逻辑,调用 dao,返回结果
    dao -- 所有与数据库相关的操作
    model -- 定义 struct 以用于 orm 映射

    不知道我的理解是否正确,同时,我还有下面一些疑惑:
    1:dao 层的作用?我在网上看的例子有一些有 dao 层,同时也有很大一部分没有这层,server 层的代码中直接调用 orm 增删改查的方法。如果 server 中每次要用到数据库的地方甚至只是参数稍有不同,就要在 dao 中写一个对应的函数,岂不是会很繁琐。而且我觉得对于像 CreateTag 这种简单方法,orm 也是直接一行语句就能实现,再单独包 dao 这一层他的优势是什么。
    2:server 层的写法?我现在的理解是有几个 controller 就要写几个对应的 server,比如有 CreateTag, ListTag, UpdateTag, DeleteTag, CreatePost, ListPost, UpdatePost, DeletePost 这 8 个 controller 是不是就要写 8 个对应的 server,那拆分出 server 层的目的仅仅就是不让业务逻辑都堆在 controller 吗,我在网上有看到说 server 层可以重用代码,但这样每加一个 controller 就要加一个 server 的,该怎么体现重用

    刚看完代码,脑子有点乱,还希望有大神能解答我的疑惑
    第 1 条附言  ·  2020-09-07 11:20:23 +08:00
    感谢大家的回复,没想到会引起关于 java 的一些争论,实在抱歉。我之前是 python+flask 入的门,所以也没接触过 dao 这类概念,才在这里问了这个问题。项目结构这种本来也没有一个定式,鱼和熊掌不可兼得,还是要在学习讨论中找到一个自己更顺手的才好。
    27 条回复    2022-03-07 20:15:34 +08:00
    xkeyideal
        1
    xkeyideal  
       2020-09-04 16:23:07 +08:00   ❤️ 7
    请把 Java 那套坏习惯改掉吧,go 不适合这套
    rimutuyuan
        2
    rimutuyuan  
       2020-09-04 16:25:15 +08:00
    mzmxcvbn
        3
    mzmxcvbn  
    OP
       2020-09-04 16:26:36 +08:00
    @xkeyideal 我也没写过 JAVA,只是看网上大部分例子都是这么划分,有什么好的 gin 的项目结构推荐的吗
    vipppppp
        4
    vipppppp  
       2020-09-04 16:28:42 +08:00   ❤️ 3
    不要什么都带入 java,要这么写用 java 不好吗
    go 的大多数人认可的项目规范:
    https://github.com/golang-standards/project-layout
    bintianbaihua
        5
    bintianbaihua  
       2020-09-04 16:33:19 +08:00   ❤️ 1
    gowk
        6
    gowk  
       2020-09-04 16:35:50 +08:00
    正在探索中,关注一下这个问题
    mzmxcvbn
        7
    mzmxcvbn  
    OP
       2020-09-04 16:42:10 +08:00
    @vipppppp 谢谢回复,我没写过 JAVA,我之前用 python/flask 写小项目的时候是最简单的只分了 model 和 controller,但我感觉对于大型项目,这样可能不太好,所以现在转到 go 希望能找到更好的项目结构方案。
    xkeyideal
        8
    xkeyideal  
       2020-09-04 16:46:07 +08:00
    @mzmxcvbn go 比较随意,写 web 项目我一般开 config, engine, httphandle, service, storage 几个目录,也不绝对,根据项目来,网上有一些建议的目录组织方式,找一个适合自己的就行,项目写多了,就能找到一个比较合适自己的了
    6IbA2bj5ip3tK49j
        9
    6IbA2bj5ip3tK49j  
       2020-09-04 17:39:07 +08:00
    1,是 Service,而不是 Server
    2,三层架构不是 Java 独有的,而且谈不上臃肿。
    windyboy
        10
    windyboy  
       2020-09-04 17:48:25 +08:00
    层太多,忘记了读数据库其实只需要写好 sql
    dongisking
        11
    dongisking  
       2020-09-04 17:49:09 +08:00
    看到 dao 就知道下面有啥评论
    basefas
        12
    basefas  
       2020-09-04 17:52:29 +08:00
    dongisking
        13
    dongisking  
       2020-09-04 17:54:05 +08:00
    linxl
        14
    linxl  
       2020-09-04 17:59:18 +08:00
    我几乎也是这么分目录的, 主要是没觉得有啥问题...
    lix7
        15
    lix7  
       2020-09-04 18:06:34 +08:00
    dao 还是要有的,未来如果需要在 data load 这个切面做事情的话,没有单独分层而是“server 层的代码中直接调用 orm 增删改查的方法。”会导致改起来很麻烦。当业务大到一定程度就没法改了。
    其实如果还处于对性能要求不高的阶段,dao 层可以很简单,只有 list 、load 、save 三个方法。

    至于 controller 和 service,我觉着确实一定程度上可以合并。现阶段大部分写事务脚本的业务,service 复用的机会不多。能复用的话也都会抽成单独的子函数。

    建议楼主实践下 ddd,代码写出来会很清晰。
    pigzzz
        16
    pigzzz  
       2020-09-04 18:07:23 +08:00
    建议楼主把 dao 换成 repository 关键字,就不会被那些反 java 的人喷了
    Yoock
        17
    Yoock  
       2020-09-04 18:09:29 +08:00 via iPhone
    有 dao 没毛病
    vipppppp
        18
    vipppppp  
       2020-09-04 18:52:20 +08:00
    建议楼主不要按 java 的写法就被打成反 java 和喷楼主,我是服了
    我想没几个开源大项目的 go 或者 python 按照这样写的
    只是觉得语言的特性不同,有时套着写会显得很累赘
    frozenshadow
        19
    frozenshadow  
       2020-09-04 21:12:31 +08:00 via Android
    @mzmxcvbn 5L @bintianbaihua 推荐的这个结构很棒,这个老哥的几篇相关博客也值得一读
    Yuiham
        20
    Yuiham  
       2020-09-04 21:25:57 +08:00 via Android
    单体应用的项目上整洁架构
    EminemW
        21
    EminemW  
       2020-09-05 19:21:28 +08:00
    如果分 controller 跟 service 的话,controller 层做参数校验
    mzmxcvbn
        22
    mzmxcvbn  
    OP
       2020-09-07 11:08:09 +08:00
    @lix7 谢谢回复!我还想请教一下有关 dao 层的问题:1.如果后续项目除了 mysql 还要用到 mongodb 或者 redis 的话,是不是相关操作也都放在 dao 层。2.dao 层里具体实现是对每一个 model 都要写自己的 list 、load 、save 函数吗,而且对与 list,我可能会有好多地方用到,但参数条件可能都不同,比如有些要多个 where,有些要 order by,有些要 limit,这是不是每用到一个不一样的,虽然都是 list,但都要再加一个函数?
    lix7
        23
    lix7  
       2020-09-07 18:59:26 +08:00   ❤️ 2
    @mzmxcvbn
    1. 都放在一层 dao 里,叫什么不重要,重要的这层只负责数据的加载和保存,你只需要调用标准接口,不需要关心存储细节;
    2. 从 DDD 的角度来讲,每一个聚合根对应一个 DAO ( DDD 里叫 repository )。但如果只从分层角度来考虑的话,是的,每一个 model 对应一个 dao ;
    3. 对于 list 接口,你自己已经提到了,where/order by/limit 都只是“参数条件”,所以他们只是一个大接口的参数而已,这个接口的基础功能,就只是 list,至于怎么 list 、list 多少个东西出来、顺序是啥样的,只是参数而已
    rita413413
        24
    rita413413  
       2020-12-11 07:42:17 +08:00 via iPhone
    @basefas 多谢😊
    joseph1994
        25
    joseph1994  
       2021-04-21 10:00:41 +08:00   ❤️ 2
    上面有些人是不是有点偏激啊,不清楚这样分层有啥大毛病,MVC 从来就不是 Java 的专利和代名词...为啥称之为“Java 的坏毛病”?再说论工程化的话,Java 有很多东西是 Go 要学的,我虽然喜欢 Go,但是真不想和这群人为伍
    waibunleung
        26
    waibunleung  
       2021-05-27 19:32:47 +08:00
    @mzmxcvbn 我有了同样的疑问,看这个帖子还是没有很好地得到解决呀...题主方便交流一下吗?
    pennai
        27
    pennai  
       2022-03-07 20:15:34 +08:00
    上面太偏激了吧,软件工程的东西,怎么扯上 java 就叫“坏毛病”了呢?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1076 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:05 · PVG 02:05 · LAX 10:05 · JFK 13:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.