新手提问: gin+gorm 中大型项目分层问题 - V2EX
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 7965 次点击
    这是一个创建于 1865 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近在看 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 不适合这套
    14v45mJPBYJW8dT7
        2
    14v45mJPBYJW8dT7  
       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
    &nbp;   27
    pennai  
       2022-03-07 20:15:34 +08:00
    上面太偏激了吧,软件工程的东西,怎么扯上 java 就叫“坏毛病”了呢?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5893 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 06:18 PVG 14:18 LAX 23:18 JFK 02:18
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86