Golang 写的 web 也分 Service 和 DAO 吗?

2021-09-09 14:14:13 +08:00
 chaleaoch

python 后端出身.

第一次写 go web. 然后照着网上的开源项目抄. 我觉得 controller service Model 三层还是可以的. 毕竟业务扔到 Service 里面逻辑更清晰一些.

然后和 Java 同事请教了一下. 令我困惑的是:

user_instance.check_passwork(request.Post['password']) 

这样不行吗? 为什么一定要

1. get password from DB
2. checkpassword with request

DB.Where(map[string]interface{}{"user_id":666}).Count(&count)

这句话必须放在 DAO 层, 而不是直接在 Service 里写? 感觉好麻烦啊.

我的问题是:

  1. GO 可以更灵活吗? 更灵活一些是套路吗? 在开源项目中 / 实际商业项目中有成功案例吗?
  2. Java 分这么多层是 JavaEE 带进来的还是 Spring 带进来的? 还是谁带进来的? 没人提出过异议吗?

谢谢

10242 次点击
所在节点    Go 编程语言
57 条回复
sutra
2021-09-09 14:19:22 +08:00
basefas
2021-09-09 14:28:16 +08:00
Go 没有严格的项目结构要求,严格来讲 Go 也不是面向对象语言,所以可以不完全按照 MVC 的架构来写。可以多看看其他的开源项目的写法。也可以看看我写的一个后台项目,以供参考。
https://github.com/basefas/admin-go
usedname
2021-09-09 14:30:48 +08:00
只要你愿意, 你在 controller 里面写 SQL 也没有任何毛病
chendy
2021-09-09 14:37:00 +08:00
不懂 go 的 java 农表示:
项目简单的话,把所有逻辑放一个文件里也没事
项目复杂的话,分层可以降低理解难度,更容易维护
这套路哪来的我不知道,但是我觉得还挺合理的
有的时候一个不复杂的功能我也会老老实实分层,有时候一个很复杂的查询我会直接塞进 controller,具体情况具体分析吧
rickiey
2021-09-09 14:39:08 +08:00
你可把一个工程写进一个 main 文件也没事,想写那都可以,但是工程大了你就发现你把握不住了,前人根据经验把工程分层分类,就是为了避免这种情况的,当然你牛逼的话也可以尝试自己的结构
sy20030260
2021-09-09 14:40:54 +08:00
1. 考虑开闭原则,例如如果后续切换存储,要做到不修改上层的业务代码逻辑,分层是不是最简单直接的方式
2. Go 风格解构了很多传统面向对象方法论里的原则,但面向接口编程和开闭原则,Go 还是提倡的
3. 代码分层不是 Java 独有而是程序员们的经验沉淀,虽然不一定是最佳实践,但在大部分场景下稳定工作
cheng6563
2021-09-09 14:43:29 +08:00
Service 和 Model 可以看情况合并一起,但请务必与 controller 层分开。
abersheeran
2021-09-09 14:53:05 +08:00
Java 程序员写 Django 也会有 DAO 。我见过。纯粹是他们的个人习惯。
rimutuyuan
2021-09-09 14:55:53 +08:00
我的 go 项目目录都是和 open bilibili 学的
soupu626
2021-09-09 14:59:34 +08:00
面向接口,功能单一独立,dao 只提供数据查询的能力,不吃任何逻辑

如果不要 service
比如在 dao 里吃了密码校验的逻辑,那如果是加盐的密码,这个加盐过程要不要 dao 吃,如果前端传递过来也是有加密的,这个加密过程要不要 dao 吃,界限很难判定

如果不要 dao,数据查询逻辑和业务逻辑混杂,也不便维护
查询一个用户是否存在,现在判定下 userId 在数据库里有没有记录就行,如果某个场景要求 lv11 以上会员可参与,某个场景要求女性专场,某个场景要求未成年禁入,这种情况下,难道在 service 里写一坨一坨的 sql 么,dao 提供一个通用的用户查询接口,给一个查询参数对象,各个场景根据需要设置不同参数就行。就算现在能忍受数据查询和业务逻辑杂,要是下一步,要求用户中心独立,数据库查询要变成外调其他服务,这一堆堆的 sql 改起来可太费劲了。

这些工程实践,都是被真实业务场景锤出来的,工程上好维护的代码才是好代码,没有维护性的代码都是屎山

当然如果是个人项目,以上纯当放屁,怎么开心怎么来。
HelloWorld556
2021-09-09 15:01:43 +08:00
zhoudaiyu
2021-09-09 15:24:39 +08:00
@abersheeran 有 IxxxService 和 xxxServiceImpl 吗?
aliveyang
2021-09-09 15:35:24 +08:00
这个工程化的东西,跟语言无关吧
kxiaong
2021-09-09 15:36:57 +08:00
即使是 Django 项目,我也不太赞成 SQL 写在 service 层( views.py ).Django 的 Model 可以封装自己的 objects, 来定义通用的查询,基本等效于 java 的 DAO 。好处是对数据库的操作封闭,所有上层业务通过统一的接口修改数据。

多人协作的 Django 项目中,没法确定别人写的 service 中有没有 SQL 修改或影响到你要操作的数据。出问题不好定位。
PDX
2021-09-09 15:41:07 +08:00
这个应该和语言无关的吧,分层设计也是经过大量实践总结才定制出来的。

你觉得怎么舒服就怎么写,后期也是要不断优化重构的,说不定最后你自己会设计出一套层次结构呢。
wfd0807
2021-09-09 15:59:38 +08:00
dao 层的存在是封装持久层,隔离业务逻辑与存储对象,比如说从 MYSQL 切换到 PostgreSQL 可以不影响业务逻辑

service 层是 spring 项目早起设计出来的,实际作用是配合切面实现事务控制,你可以把 service 层理解成事务脚本

至于你的项目需要不需要,根据以上两点自行考虑
Jooooooooo
2021-09-09 16:01:37 +08:00
分层还真的和语言无关.

分层想解决的问题也是独立于语言的.
Macv1994
2021-09-09 16:04:18 +08:00
个人习惯吧
chaleaoch
2021-09-09 16:18:03 +08:00
@soupu626 #10
如果某个场景要求 lv11 以上会员可参与,某个场景要求女性专场,某个场景要求未成年禁入,这种情况下,难道在 service 里写一坨一坨的 sql 么,dao 提供一个通用的用户查询接口,给一个查询参数对象,各个场景根据需要设置不同参数就行。
===================
谢谢, 再次基础上 我们把业务更加的复杂化. 有时候我们需要 lv11 + 有孩子的女性. 是否有孩子 是从另一张关联表读取并且他们之间没有数据库层面的外键关系.

像这样的场景是不是就应该把方法放到 Service 里面而不是 DAO 里了?

所以想请教, DAO 里面可以带业务吗?
hihanley
2021-09-09 18:04:45 +08:00
@basefas 我有一个问题,internal 包里面的内容不是只有直接父级才可以访问吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/800816

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX