当前位置: 首页 > 知识库问答 >
问题:

java - 关于后端开发分层的疑问?

於炯
2024-05-06

简单来说 controller service dao 三层。

controller 和 service 之间的分层相对比较清晰, 业务逻辑和显示逻辑的拆分, 譬如 MQ/http/RPC 和业务分离。

service 和 dao 的区分我有点搞不懂。主要是因为分不清什么是存储逻辑(非业务逻辑)什么是业务逻辑。 尤其是加入了 manager 层之后。

因为是 python 后端, 所以很自然的将业务逻辑加到 Model 上。 (我理解这里的 Model 是指业务 Model ) UserModel.is_super() 带业务的查询。
或者
UserModel.objects.all() 原生将 permissons,groups ,Commany,等等一起都带过来了。
或者
UserModel.* 做一些跨表的操作。

我的问题:

什么是业务逻辑, 什么是非业务逻辑。
我的理解是,客户看不到的逻辑都算非业务逻辑, 譬如
1.1 表结构,表关联关系等。
UserManager.delete()和DepartmentManager.delete() 这俩可以同时包含删除关联关系表( UserDeptModel )的能力。不是二取一。 同理 save 也是。 如果没有 manager 层, 那么我的理解 Dao 是可以做连/跨表操作的,只要这个跨表操作和业务无关,没必要在 service 调用两次 dao 。

class UserManager:    def delete():        UserDao.delete()        UserDeptDao.delete()class DepartmentManager:    def delete():        DepartmentDao.delete()        UserDeptDao.delete()

1.2 密码加盐。
用户最多只需要知道你的密码是不明文保存就可以了。 加盐动作可以放在 DAO/Manager 层处理。

class UserDao:    def make_password(passwd):        return salt(passwd)    def save():        passwd = self.make_password(passwd)        self.passwd = passwd        super.save()

1.3 DAO 层的方法命名和设定
是否可以类似get_super_user 这种带有非业务逻辑(假设这个 super 与业务逻辑无关),但是具有明显语义的方法名?还是只能get_user_by_type("super")
1.4 http 请求也可以封装层 dao. 譬如后端有一些依赖(另一个 team 提供支持), 我可以将这些依赖封装成 dao, 而不是 service.

  1. 在 django/flask 中, 很容易实现 django filter 的功能。 https://www.django-rest-framework.org/api-guide/filtering/
    https://django-filter.readthedocs.io/en/stable/
    甚至于在 ModelViewSet 中直接集成了 filter, https://github.com/encode/django-rest-framework/blob/master/rest_framework/mixins.py#L33 如果用 python 做三层架构且想实现类似 django filter 功能的话, 那么 DAO 中一定需要传入 request 参数。且层层穿透。在没有 spring 这种自动注入框架的帮助下,如何处理类似的问题? java 中是如何实现类似 django filter 类似功能的?
  2. 什么是数据实体? 是否 controller service dao 是一一对应的,如果不是, 能否举几个例子。 主要是 DAO 和 service.

三层架构和 DDD 的优缺点建议不再本贴讨论。担心歪楼。 谢谢大家啦!

共有1个答案

冷吉星
2024-05-06

问题太大了,只能从java的说一些比较宏观抽象的

分层的目的本身是为了按照职责对系统进行拆分,由外而内:

  1. 暴露对外的一层,XXController,很薄,仅作为入口
  2. 执行业务的一层,XXService,最厚最核心
  3. 执行对‘内’的一层,通常是访问数据库,但是也可能是访问三方接口,本地文件等等

所以service和dao的区别就很明确:dao只做对接,不承接业务
比如说有一个‘创建用户‘的逻辑,service里会’查询用户名是否重复‘然后’创建用户‘,对应的dao里就会有’根据用户名查询用户‘和’保存用户‘的方法

至于持久如何实现,是active record模式还是dao模式,其实大差不差
DDD和贫血模型其实也并不完全冲突,实际工程体验下来,贫血模型还是更容易理解一点

 类似资料:
  • 刚开始学后端,有几个问题想要请教下大家 1 是使用maven,还是IDEA的提供的intellij?不使用另一个的原因是? 2 如果是使用maven的话,是使用IDEA自带的maven,还是自己额外下载?看的一些网上教程都是让自己单独下载maven,说IDEA自带的maven不方便配置。 谢谢

  • PostgreSQL 官方文档关于部分索引给了以下一个示例: Example 11.2. Setting up a Partial Index to Exclude Uninteresting Values If you have a table that contains both billed and unbilled orders, where the unbilled orders tak

  • young gc是不是针对所有的新生代region进行回收?我的理解是young gc会回收全部的新生代Region,并调整Eden区数量来满足软实时性要求; Oracle文档中指出在并发标记期间还可能进行额外的young gc,这不会破坏并发标记期间的内存布局么?比如现在正在进行并发标记,对于某个Eden Region A, 还未完成标记,此时若是发生young gc,A会被如何处理? 以及这位

  • 前言 上一篇我们遇到'少年,是不是忘了npm run mock?'的警告,这一篇我们就来解决这个问题。 开发 一、安装包 安装koa和一系列的包(我们用的是koa v2): koa koa-bodyparser koa-router boom nodemon mockjs 解释说明一下(知道的同学可以忽略): 名称 作用 koa 我们都知道Node.js有HTTP模块,来处理HTTP请求

  • 以下代码在 chrome 输出 1,2,3 这个在网上找到了,forEach 一开始就已经获取了 数组长度 The range of elements processed by forEach is set before the first call to callbackfn. Elements which are appended to the array after the call to

  • 例如我创建了一个dataHook main.ts中 页面有个按钮就执行v.value += 1,为什么console.log还是原值1呢?