dao层如何调用对象_你的项目应该如何正确分层?

00d02c54a632aae134aa43386bef957e.png

你好,欢迎收听极客视点。

说起应用分层,大部分人都会认为这不是很简单嘛,就Controller、Service、Mapper三层。但在“简单”背后,很多人并没有将各层级的职责划分清楚。比如在很多代码中,Controller比Service还多,Service被当成透传了,这是开发代码容易被忽略的地方。这样往往造成层级关系混乱,后续代码无法复用、维护困难。

此前,公众号“咖啡拿铁(ID:close_3092860495)”介绍了优化代码分层的方法,供你参考。

如何进行分层

一个好的应用分层需要具备以下几点:

  • 方便后续代码进行维护扩展;
  • 分层的效果需要让整个团队都接受;
  • 各层的职责边界清晰。

阿里巴巴的分层规范

da3d5f59933cdf8c8191aadc53c1c1f1.png 在阿里的编码规范中,对分层的要求如下:

1. 开放接口层:可直接封装 Service 方法暴露成 RPC 接口;通过 Web 封装成 http 接口;进行网关安全控制、流量控制等。

2. 终端显示层:各个端的模板渲染并执行显示的层。当前主要是 velocity 渲染、JS 渲染、JSP 渲染、移动端展示等。

3. Web 层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。

4. Service 层:相对具体的业务逻辑服务层。

5. Manager 层:通用业务处理层,它有如下特征:一是对第三方平台封装的层,预处理返回结果及转化异常信息;二是对Service层通用能力的下沉,如缓存方案、中间件通用处理;三是与DAO层交互,对多个DAO的组合复用。

6 .DAO 层:数据访问层,与底层 MySQL、Oracle、Hbase 进行数据交互。

阿里巴巴规约中的分层比较清晰,简单明了,但是描述得还是过于简单了,很多人还是分不清楚Service层和Manager层之间的关系,导致很多项目中根本没有Manager层的存在。下面介绍具体业务中应该如何实现分层。

优化分层

首先需要说明的是,如果RPC框架选用Thrift,可能会比其他的RPC框架多出一层,作用和Controller层类似:

ca0d4dea19cf676fed4f88f6efdbc46b.png
最上层的Controller和TService是阿里分层规范中的第一层:轻业务逻辑、参数校验、异常兜底。通常这种接口可以轻易更换接口类型,所以业务逻辑必须要轻,甚至不做具体逻辑。

其次是Service层,这是业务层,复用性较低,这里推荐每一个Controller方法都对应一个Service,不要把业务编排放在Controller中去做,否则以后你要接入Thrift,又需要把业务编排再做一次,这会导致你每接入一个入口层,代码都得重新复制一份。如下图所示:

c2b1fe467d6f465a908499f41179cbc8.png 这样大量的重复工作必定会导致开发效率下降,所以你要把业务编排逻辑都放进Service层中。

2f7a58565f57279eb6b1189c1b19998f.png
然后是Mannager层,这是可复用逻辑层。这里的Mannager可以是单个服务,比如Cache、MQ等等;也可以是复合的,当你需要调用多个Mannager时,可以将它们合为一个Mannager,比如逻辑上的连表查询等。如果是httpMannager或rpcMannager,还需要在这一层做一些数据转换。

再来看DAO层,这是数据库访问层。主要负责“操作数据库的某张表,映射到某个Java对象”,DAO应该只允许自己的Service访问。

最后顺便聊一聊分层领域模型的转换,在阿里巴巴编码规约中,列举了下面几个领域模型规约:

  • DO(Data Object):与数据库表结构一一对应,通过DAO层向上传输数据源对象。
  • DTO(Data Transfer Object):数据传输对象,Service或Manager向外传输的对象。
  • BO(Business Object):业务对象,由Service层输出的封装业务逻辑的对象。
  • AO(Application Object):应用对象,在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
  • VO(View Object):显示层对象,通常是Web向模板渲染引擎层传输的对象。
  • Query:数据查询对象,各层接收上层的查询请求。注意超过2个参数的查询封装,禁止使用Map类来传输。

3d9d162e1d503833c66e16a2c7e7ba4f.png 每一个层基本都有自己对应的领域模型,而有些人过于追求每一层都用自己的领域模型,这就导致在一次请求中,出现多次对象转换。

一个折中的方案是:

  • 允许Service/Manager可以操作数据领域模型。
  • Controller/TService层的领域模型不允许传入DAO层,这样就不符合职责划分了。
  • 同理,不允许DAO层的数据传入到Controller/TService。

总结

业务分层对于代码规范是比较重要的,决定后续代码是否可复用,是否职责清晰、边界清晰。

以上就是今天的内容,如果你的团队有更好的分层方法,欢迎留言分享。

897d0c143961ede0cbf93570b8ac0d06.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/527198.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

combobox 如何让text居中_MFC 中ListBox 与 ComboBox 中的文本如何实现水平居中与垂直居中 - 小众知识...

MFC 中, ListBox 与 ComboBox 中的项在设置了高度的情况下如何实现文本的水平居中与垂直居中???ListBox 与 ComboBox 中的数据均为动态添加文本内容含有数字、英文、中文void CMyComboBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemS…

android 子module混淆_Android 多模块打包混淆填坑记

最近有个 sdk 的项目使用了多模块(Module)开发,然后提供 jar 包给接入者使用,要求大部分类是混淆过的,保留几个接口,Android Studio 能够导出 aar 文件,对于导出 jar 却要大费一番周折。我在网上找到这个比较靠谱的解决…

mysql索引_MySQL索引介绍和实战

索引是什么MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。可以得到索引的本质:索引是数据结构,索引的目的是提高查询效率,可以类比英语新华字典,根据目录定位词语如果没有目录呢&#xff0c…

mysql自增字段_MySQL自增字段的常用语句

学习MySQL数据库,MySQL自增字段是最基础的部分之一,下面为您介绍一些MySQL自增字段的常用语句,希望对您学习MySQL自增字段能些许帮助。1、创建表格时添加: create table table1(id int auto_increment primary key,...)2、创建表格…

mysql安装需要注意什么意思_mysql 安装过程及注意事项

1.1. 下载:我下载的是64位系统的zip包:下载zip的包:下载后解压:D:\软件安装包\mysql-5.7.20-winx641.2. 配置环境变量:变量名:MYSQL_HOME变量值:E:\mysql-5.7.20-winx64path里添加:%…

mysql 语句检查_mysql查询语句

一、简单查询1.最简单查询(查所有数据)select * from 表名 注意:* 代表所有列,并不是代表所有行例:select * from test2.查询指定列select 列名,列名 from 表名例:select code,name from test3.修改结果集的列名 asselect 列名 …

mysql索引 物理文件_MySQL体系结构之物理文件

一、MySQL日志文件mysql日志文件及功能:日志文件功能错误日志记录启动、停止、运行过程中mysqld时出现的问题通用日志记录建立客户端连接和执行的语句二进制日志记录更改数据的所有语句,还用于复制慢查询日志记录执行时间超过long_query_time秒的所有查询…

mysql每次查询1000条数据库_30多条mysql数据库优化方法,千万级数据库记录查询轻松解决...

1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,Sql 代码 : select id from t where …

mysql count转字符串_MySQL字符串函数

把字符串转成小写mysql> select sex,LCASE(job) from string_test where jobDUCK;------------------| sex | LCASE(job) |------------------| 1 | duck |------------------1 row in set (0.00 sec)3,FIND_IN_SET(str,strlist)4,FIELD(str,str1,str…

gitlab 端口_安装Gitlab-注意端口

文档本身并没有什么特殊,安装也很简单,只是修改端口这里如果有需要的可以看一下安装Gitlab[rootdeploy ~]# sudo yum -y install gitlab-ce默认端口是8080,避免冲突还是修改一下[rootlocalhost ~]# cat /etc/gitlab/gitlab.rb |grep 192.168.…

MySQL read-c_技术分享 | MySQL C API 参数 MYSQL_OPT_READ_TIMEOUT 的一些行为分析

作者:戴岳兵MYSQL_OPT_READ_TIMEOUT 是 MySQL c api 客户端中用来设置读取超时时间的参数。在 MySQL 的官方文档中,该参数的描述是这样的:MYSQL_OPT_READ_TIMEOUT (argument type: unsigned int *)The timeout in seconds for each attempt t…

mysql出现core dumped_mysql-为什么我遇到分段错误(核心已转储)?

这是我要运行的代码.它可以编译,并且工作良好,直到昨天.#include #include int main(int argc, char **argv){MYSQL *conn;MYSQL_RES *result;MYSQL_ROW row;int num_fields;int i;conn mysql_init(NULL);mysql_real_connect(conn, "hostname", "username"…

mysql解释中fitered_MySQL的explain中的参数说明

1、id每个被独立执行的操作的标识,表示对象被操作的顺序;id值大,先被执行;如果相同,执行顺序从上到下。若没有子查询和联合查询,id则都是1。Mysql会按照id从大到小的顺序执行query,在id相同的情…

vue脚手架搭建项目_复习之vue脚手架搭建项目的两种方法

安装脚手架node 版本要求: > 8.9 。关于旧版本:如果在这之前已经全局安装了旧版本的vue-cli(1.x 或 2.x),那么需要先卸载掉。卸载旧版本运行:npm uninstall vue-cli -g 或 yarn global remove vue-cli。安装vue/cli&#xff1a…

ubuntu修改mysql账户密码_Ubuntu修改mysql用户重置密码

编辑mysql的配置文件/etc/mysql/my.cnf,或者/etc/mysql//mysql.conf.d/mysqld.cnf,在[mysqld]段下加入一行“skip-grant-tables”。1、安装$ sudo apt-get install mysql-server$ apt install mysql-client$ apt install libmysqlclient-dev以此在终端输入上述代码&…

pythonsocket中tcp通信接收不到数据_TCP 为什么三次握手而不是两次握手(正解版)...

先说结论为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始…

mysql高级查询面试_高级MySQL数据库面试问题 附答案

因为有大家的支持,我们才能做到现在,感谢你们这一路上对我们的支持.在这篇文章中,我们将主要针对MySQL的实用技巧,讲讲面试中相关的问题.1. 如何使用SELECT语句找到你正在运行的服务器的版本并打印出当前数据库的名称?答&#xf…

ecshop清除mysql缓存_ECSHOP缓存清理关闭教程

ECSHOP的缓存存放在templates/caches/文章夹下,时间长了这个文件夹就会非常庞大,拖慢网站速度。还有很多情况我们不需要他的缓存。本文介绍禁用ECSHOP缓存的方法。ECSHOP的缓存有两部分,一部分是SMARTY的页面缓存;另一部分是SQL查…

mysql无法启动如何备份文件_mysql 5.7 停电导致无法启动、如何备份数据,重新安装mysql...

用于记录服务器停电导致,mysql启动失败后,如何备份数据,重新安装mysql,主要分为数据备份,mysql重新安装。1、mysql无法启动时,进行数据备份。执行:systemctl start mysqld,启动失败。…

python tkinter entry默认值_Python ---(六)Tkinter窗口组件:Entry

The Tkinter Entry Widget##简介Entry(输入框)组件通常用于获取用户的输入文本。##何时使用 Entry 组件?Entry 组件仅允许用于输入一行文本,如果用于输入的字符串长度比该组件可显示空间更长,那内容将被滚动。这意味着该字符串将不能被全部看…