本文给大家介绍必须定义入口点什么意思对应的知识点,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
一、代码结构中Dao,Service,Controller,Util,Model是什么意思,为什么划分?
先名词解释吧:
DAO=DataAccessObject=数据存取对象
Service=服务
Controller=控制器
Util=工具
Model=模型
首先,一个代码是不是有完善的结构,和是不是有上面这些东西没有什么关系,只是通常来说,我们做一个大项目会把项目分解成很多不不同的模块(Module),然后根据用途和角色,我们对这些模块有一个通用的命名规则,这也就是上面这些英文单词的来历。
所以,请一定记住,项目中是否包含这些模块或者单词,和你的项目结构是否完善一毛钱关系没有。但是当你的项目结构相对完善的时候,你会发现有这样一些角色的存在。
接下来一个个的来详细讨论一下这个东西是怎样出现的:
DAO,数据存取对象。通常我们会遇到很多要和数据库打交道的场景,如果为每一个场景都去写一些SQL语句,会让我们代码变得很奇怪,我们希望我们的代码比较干净整洁,那么一个很容易想到的方案就是把数据库封装一下,让我们和数据库的交道看起来比较像和一个对象打交道。这个对象通常就是DAO,当我们操作这个对象的时候,这个对象会自动的产生SQL语句来和数据库打交道,而我们只需要和DAO打交道就可以了。
当然,从本质上来说,DAO并不需要和数据库有什么必然的联系,DAO只是数据存取对象的缩写,所以只要是把数据持久化包装成一个对象的访问(读写),这种对象都可以被称之为DAO,譬如,用JSON格式存到硬盘上。
Service,我们有时候会需要一些相对独立,与业务系统没啥关系的功能。但不是所有的功能都可以做成一个服务,服务是一个相对独立的功能模块,完成一些指定的工作,这些工作高度抽象和通用。一个典型的服务像是数据库服务、缓存服务、文件存储服务、身份验证服务、消息队列服务等。
关系型数据库服务可以视为是一个接收SQL语句并给出一个查询结果的服务,我们不必关心服务内部具体是怎样处理问题的,我们只需要关注服务给出的接口。
并不是所有的模块都适合做成服务,一个服务首先最重要的是独立性,这个服务必须可以独立的完成指定的工作。复杂的服务可能依赖于一个或者多个更基础的服务,但是服务通常不应当依赖于任何具体的业务代码,服务必须具有高度的抽象性。关系型数据库服务就具有高度的抽象性,事实上只要我们撰写标准的SQL,不论后面是MySQL、SQLServer还是Oracle,他们都会呈现出几乎完全相同的行为。
一个更为简单的服务像是缓存服务,我们把一坨数据放进去,在一段时间内可以快速的获取这坨数据,在一段时间后数据就会消失。
当你的代码需要一个高度抽象高度标准化的功能,而这个功能又不能简单的实现,或者这个功能需要很多资源的配合,例如缓存服务需要内存资源,而数据库服务通常需要磁盘资源,身份验证服务通常需要数据库服务支持。这个时候就可以考虑将这个功能模块做成一个服务。
服务作为基础的部件,我们通常会要求它能够应付各种各样的情况,一个优质的服务通常会有非常高的可用性,因为我们的系统可能会依赖于各种各样的服务,而整个系统的可用性将不可能比其中任何一个服务的可用性更高。
所以服务的特征:抽象、独立、稳定。
评论中提到Java项目中的Service通常是指BusinessService,这里也简单说说。
很多时候,我们发现服务的特征对于我们开发一个大型项目的时候很有帮助。就拿独立性来说,关系型数据库服务如SQLServer可以独立发售,独立安装和部署。它可以自行测试自己的接口,如果都达到了预期的效果,并且能够应付各种情况,这个服务就可以作为一个产品独立的出售给我们安装。这意味着关系型数据库服务并不需要配合我们的业务系统一起进行测试和调试,或者作出什么变更。
在完成一个大型的业务系统时,我们发现一些子模块或者子系统也可以像服务一样独立的部署和测试。例如会员系统、支付系统、订单系统等等,他们的业务逻辑可能非常复杂,但是逻辑相对独立,并且高度内聚。如果我们将这些系统分别独立的测试和部署,就可以大大的降低我们的测试、部署和运维的成本。
这些可以独自完成某一方面业务功能,高度内聚,可以独立部署测试的模块,我们可以称之为BusinessService,业务服务。它同样具有服务的特征,抽象、独立和稳定。一个会员系统内部的逻辑可能非常复杂(积分规则,分级规则,风险控制,行为数据),但是在其外部,会员的概念可以非常简单。
Util,Util通常来说是我们找不到合适的名字的时候的选择,Util就是工具,在做项目的时候我们总会遇到一些奇奇怪怪的小功能或者重复的代码需要提取。像是URL编码或者解码(当然这个类库通常会提供,不过就以.NETFramework为例,提供这个方法的类型名称叫做HttpUtility),或是自创的加密签名算法等等。
Model,模型,通常来讲,我们会把模型和另一个东西放在一起来说:View,视图。
模型通常认为是视图的内核,何谓之视图?我们正在与之交互的知乎网站的界面就是视图,而模型是指他的内核:数据。
知乎的数据是问题和答案,问题分为标题和描述,答案有内容和作者以及各种状态。知乎有很多个UI,例如移动页面,普通PC页面,手机APP,以及改版前的旧界面,这些被称作不同的视图。而所有这些形态迥异的视图,其内核都是一样的,这个内核我们就称之为模型(Model)。
将Model和View的概念拆分开来,有助于我们关注不同的方面,也可以更有效的分工。有些工程师更关注于内核也就是模型,通常来说,他们被称之为后端工程师。有些工程师更关注于用户界面的交互和展示,通常来说,他们被称之为前端工程师。
未完待续……
二、屮艸芔茻 甚么意思
屮音chè,本义是草木初生,引伸有贯穿的意思,是彻的古字;艸音cǎo,是草的古字;芔音huì,本义是各种草的总称,今作卉;茻音mǎng,本义指密生的草,是莽的古字。
三、代码结构中Dao,Service,Controller,Util,Model是什么意思,为什么划分?
代码结构中Dao,Service,Controller,Util,Model等等这些名称,体现了项目代码的分层。
说起分层,我们可以结合着阿里开发规范,看看代码分层的门道。
大部分人都会认为分层不是很简单嘛,就controller,service,mapper三层。看起来简单,很多人其实并没有把他们职责划分开,在很多代码中,controller做的逻辑比service还多,service往往当成透传了,这其实是很多人开发代码都没有注意到的地方,反正功能也能用,至于放哪无所谓呗。这样往往造成后面代码无法复用,层级关系混乱,对后续代码的维护非常麻烦。
的确在这些人眼中分层只是一个形式,前辈们的代码这么写的,其他项目代码这么写的,那么我也这么跟着写。但是在真正的团队开发中每个人的习惯都不同,写出来的代码必然带着自己的标签,有的人习惯controller写大量的业务逻辑,有的人习惯在service中之间调用远程服务,这样就导致了每个人的开发代码风格完全不同,后续其他人修改的时候,一看,我靠这个人写的代码和我平常的习惯完全不同,修改的时候到底是按着自己以前的习惯改,还是跟着前辈们走,这又是个艰难的选择,选择一旦有偏差,你的后辈又维护你的代码的时候,恐怕就要骂人了。
所以一个好的应用分层需要具备以下几点:
方便后续代码进行维护扩展。分层的效果需要让整个团队都接受各个层职责边界清晰1.怎样进行分层1.1阿里规范在阿里的编码规范中约束的分层如下:
开放接口层:可直接封装Service方法暴露成RPC接口;通过Web封装成http接口;进行网关安全控制、流量控制等。
终端显示层:各个端的模板渲染并执行显示的层。当前主要是velocity渲染,JS渲染,JSP渲染,移动端展示等。
Web层:主要是对访问控制进行转发,各类基本参数校验,或者不复用的业务简单处理等。
Service层:相对具体的业务逻辑服务层。
Manager层:通用业务处理层,它有如下特征:1.对第三方平台封装的层,预处理返回结果及转化异常信息;2.对Service层通用能力的下沉,如缓存方案、中间件通用处理;3.与DAO层交互,对多个DAO的组合复用。
DAO层:数据访问层,与底层MySQL、Oracle、Hbase进行数据交互。
阿里巴巴规约中的分层比较清晰简单明了,但是描述得还是过于简单了,以及service层和manager层有很多同学还是有点分不清楚之间的关系,就导致了很多项目中根本没有Manager层的存在。
下面介绍一下具体业务中应该怎样实现分层
1.2优化分层从我们的业务开发中总结了一个较为的理想模型,这里要先说明一下由于我们的rpc框架选用的是thrift可能会比其他的一些rpc框架例如dubbo会多出一层,作用和controller层类似
1.最上层controller和TService是我们阿里分层规范里面的第一层:轻业务逻辑,参数校验,异常兜底。通常这种接口可以轻易更换接口类型,所以业务逻辑必须要轻,甚至不做具体逻辑。
2.Service:业务层,复用性较低,这里推荐每一个controller方法都得对应一个service,不要把业务编排放在controller中去做,为什么呢?如果我们把业务编排放在controller层去做的话,如果以后我们要接入thrift,我们这里又需要把业务编排在做一次,这样会导致我们每接入一个入口层这个代码都得重新复制一份如下图所示:
这样大量的重复工作必定会导致我们开发效率下降,所以我们需要把业务编排逻辑都得放进service中去做:
3.Mannager:可复用逻辑层。这里的Mannager可以是单个服务的,比如我们的cache,mq等等,当然也可以是复合的,当你需要调用多个Mannager的时候,这个可以合为一个Mannager,比如逻辑上的连表查询等。如果是httpMannager或rpcMannager需要在这一层做一些数据转换
4.DAO:数据库访问层。主要负责“操作数据库的某张表,映射到某个java对象”,dao应该只允许自己的Service访问,其他Service要访问我的数据必须通过对应的Service。
2.分层领域模型的转换在阿里巴巴编码规约中列举了下面几个领域模型规约:
DO(DataObject):与数据库表结构一一对应,通过DAO层向上传输数据源对象。DTO(DataTransferObject):数据传输对象,Service或Manager向外传输的对象。BO(BusinessObject):业务对象。由Service层输出的封装业务逻辑的对象。AO(ApplicationObject):应用对象。在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。VO(ViewObject):显示层对象,通常是Web向模板渲染引擎层传输的对象。Query:数据查询对象,各层接收上层的查询请求。注意超过2个参数的查询封装,禁止使用Map类来传输。层次领域模型
Controller/TService VO/DTO
Service/Manager AO/BO
DAO DO
每一个层基本都自己对应的领域模型,这样就导致了有些人过于追求每一层都是用自己的领域模型,这样就导致了一个对象可能会出现3次甚至4次转换在一次请求中,当返回的时候同样也会出现3-4次转换,这样有可能一次完整的请求-返回会出现很多次对象转换。如果在开发中真的按照这么来,恐怕就别写其他的了,一天就光写这个重复无用的逻辑算了吧。
所以我们得采取一个折中的方案:
1.允许Service/Manager可以操作数据领域模型,对于这个层级来说,本来自己做的工作也是做的是业务逻辑处理和数据组装。
2.Controller/TService层的领域模型不允许传入DAO层,这样就不符合职责划分了。
3.同理,不允许DAO层的数据传入到Controller/TService.
总结总的来说业务分层对于代码规范是比较重要,决定着以后的代码是否可复用,是否职责清晰,边界清晰。
当然这种分层其实见仁见智,团队中的所有人的分层习惯也不同,所以很难权衡出一个标准的准则,总的来说只要满足职责逻辑清晰,后续维护容易,就是好的分层。
作者:咖啡拿铁
链接:https://juejin.cn/post/6844903636334542856
来源:掘金