V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
mzmxcvbn

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

  •  
  •   mzmxcvbn · Sep 4, 2020 · 8410 views
    This topic created in 2070 days ago, the information mentioned may be changed or developed.
    最近在看 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 的,该怎么体现重用

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

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

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