知乎的
从名字上看:
UserDAO数据层接口,上接服务层,下接数据库
UserDAOImpl 是UserDAO的实现类,具体操作数据库的
UserService服务层,上接用户层,下接数据层
UserServiceImpl 服务层UserService的实现类
User**Action用户层,根据用户请求调用service
比如,用户在网页上点击登录,我们把这个请求叫login吧
User**Action会接到这个action请求,发现这是个登陆请求login,这里可以进行一下初步的验证,比如用户名格式,密码格式,如果没问题,那么它就调用service中的login登陆方法,在UserServiceImpl进行验证,比如用户名和密码是否正确。怎么验证呢?UserServiceImpl会调用DAO层的方法,DAO会从数据库中查询。
例如用户是张三,密码是111,的用户登录了
User**Action接到请求,请求类型是login,用户名张三,密码111,
做初步判断,用户名不是空的,密码不是空的,格式正确,好,调用service中的方法,传递参数是张三和111
service接到命令,调用DAO的方法,传递参数张三,DAO链接数据库,根据张三这个用户名查到用户信息(包括用户密码),如果没有,证明用户名写错了或者没注册。如果有,那么把结果返回给service
service接到返回的内容,看一下DAO返回的密码是不是111,如果是,那就登陆成功,如果不是,提示密码错误。将处理结果返回给User**Action,
User**Action接到返回结果,在显示到页面上给用户看。
你也可以问为什么分这么多层?不一起直接写?
可以直接写,但是很乱。这样分层,把逻辑都分割,很多地方都可以共用。
还拿登陆和注册来说,登陆的时候要用到根据用户名查询细信息,注册的时候也要判断用户名是否存在。如果你不分层,都写在User**Action里,是不是同样的代码要写两次呢?
而且出了问题也不好查找出在哪里。比如404错误,通常是找不到页面,可以很快的知道是在User**Action里面,数据库操作错误,马上就知道是在DAO里面
Java中 PO、DO、DTO、VO、FormBean的通俗解释。
假如数据库中有表Person分别有几个字段,姓名、性别(0,1)、生日(date)、密码,前端查询界面需要查看Person的信息。
PO:
persistant object持久对象
最形象的理解就是一个PO就是数据库中的一条记录。 好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象。
DO:
个人简单理解就是类似托管的PO,操作DO不会影响数据库的数据。
DTO:
数据传输对象。例如前台查询不会返回密码只是返回 姓名、性别、生日,于是我们将信息封装到DTO中进行传输。
VO:
value object值对象、view object视图对象。
主要用于业务层之间的数据传递,属性是根据当前业务的不同而不同的。
应用场景:获取的DTO数据中性别信息为0和1,但要求:手机上展示为帅哥和美女,而web端显示为男和女。
FormBean:
它只是HTML表单的封装,是为了在控制层弱化request中存储数据的作用,将request的get方法转变为对象的存取值。
如果让FormBean直接到业务层(它本来应该生活在控制层),View和Model就出现了强耦合,如果想改一下view的表示,整个业务逻辑都得改,恐怖的事情啊。
应用场景:
假如需要查询Person信息,并返回给前端” 姓名、年龄、是否成年 “。如果将FormBean直接作用与业务层,那么相关联的业务中都会设置这个”是否未成年“的字段,显然这不可取的。如果用VO处理业务那么简单多了,相关联的业务就不会受到影响,只需在FromBean里加一个字段就可以了,然后将VO转为FormBean交给前端。
怎么将dto对象从jsp传入java
两种方式:一种是使用普通的Java方式,直接生成实体类的实例、业务类的实例,对实体类实例赋值后,调用业务类实例的方法,即可以将值传入后端的Java中;
另一种方式是使用JSP标准动作,<jsp:useBean
id="">定义JavaBean实例,<jsp:setProperty
property="*">对JavaBean实例进行赋值,可以将值传入后端的Java中;
多写几个类实现接口,在实现类中分别写几个接口中没有的方法,然后使用
接口 对象名 = new 类名;
类名 对象名 = new 类名;
实例化对象调用方法,你就会发现使用接口 对象名 = new 类名; 方式实例化的对象只能调用接口中有的方法,而不能调用类中特有的方法。而使用类名 对象名 = new 类名;方式创建出来的对象可以调用所有的方法
使用接口编程的好处是统一规范化。
你会发现无论多少个实现类,无论这些实现类有什么不同,使用接口 对象名 = new 类名; 方式实例化对象都可以调用接口中定义的方法
JavaWeb开发中,服务器端通常分为表示层,业务层,持久层,这就是所谓的三层架构,三层架构的每一层都有自己的开发模式,即架构模式,如下图
其中,表示层一般是采用MVC架构模式,业务层有事务脚本模式同领域模型模式等,持久层有数据映射器模式(Hibernate是典型的)、入口模式(iBatis,JDBC),企业应用中最关键的显然是业务层,而对于初学者来说,事务脚本模式是最简单,最容易掌握的。如果开发团队面向对象设计能力一般,而且业务逻辑相对简单,业务层一般都会采用事务脚本模式。为啥?简单,(如果业务逻辑复杂,用事务脚本模式就不明智了,简单讲,就是违背了单一职责设计原则,Service类成为万能的上帝,承担了太多职责。。)
什么是事务脚本模式呢?
所谓事物,就是表示层的一个请求;所谓脚本就是一个方法或者一个函数;所谓事务脚本就是将一次请求封装为一个方法或者一个函数。所谓事务脚本模式,就是将业务层的对象分为三类,按照下图的方式组织起来(下图是UML类图)
如上图所示,在事务脚本模式中,有三类对象,其中,Service类封装业务流程(或者说是界面上的业务流程),DAO类封装对持久层的访问,DTO类封装业务实体对象。各个对象之间的关系如上图所示,这就是所谓业务逻辑的组织方式。
为什么要用Sevice接口同DAO接口?我们还得回到最基本的面对对象设计原则上去。
面对对象设计原则中有三条与此相关:开闭原则、依赖倒转原则、里氏替代原则。还记得依赖倒转原则吗?高层不依赖于低层,二者都依赖于抽象,也就是面对接口编程。
为什么要用Service接口?是让表示层不依赖于业务层的具体实现,为什么要用DAO接口?是让业务层不依赖于持久层的具体实现。有了这两个接口,SpringIOC容器才能发挥作用。
举个例子,用DAO接口,那么持久层用Hibernate,还是用iBatis,还是JDBC,随时可以替换,不用修改业务层Service类的代码。
使用接口是为了调用与实现解耦,带来的好处是可以各干各的,带来的坏处是从一个概念变成了两个概念,增加了系统的复杂度,衡量一下,做选择。大部分要考虑会不会写接口,没有良好接口设计能力的人,写出来的接口抽象不合理,等于没有写,什么好处都得不到,只有坏处,这种情况下干脆别写,那么怎么衡量你会不会写接口?经验是至少见过一次写接口后得到明确好处的例子。
什么情况下需要各干各的?
最简单的场景,写接口的是你,写实现的是你小弟。当然大多数类似情况没有必要真的建一个interface然后让人家去implements,把函数的第一行写好,注释写好,代码提交上,里面内容让小弟去填写就行了,
另一种情况,调用代码先于实现代码编写。比如你开发的是struts这种东西,那你指定得搞个Action接口。
再一种情况,多种业务的模式类似。此时这个接口类实际上相当于某一层的抽象。定义出一个层后,有多种实现,然后通过向调用端注入不同的实现类,实现不同的逻辑。如果这种注入不能在编译期完成的话,就需要用接口抽象一下。
说到题目中的场景
Dao,这是做数据库读写的,对应一下上面的几种情况:可能需要写个interface里面几个抽象的insert、delete之类的函数;项目如果切换oracle同mysql,需要定义个dao接口,每个类都有一个dao,每个dao都有crud基本方法的话你可能需要定义个通用dao接口然后搞点代码技巧不用一个个去写,所以dao接口还是有用的。
Service,具体问题具体分析,不抠理论,理解就是一段段实现了某个逻辑的代码的组合,所以service是个比dao更抽象的概念,严格说dao就是service,只不过javaweb开发中,dao是人人都写,所以拿出来单说了
从工序上说,写上一层会用到下一层提供的逻辑,具体表现形式就是各种各样的service类和里面的方法,上一层开始时,一定会知道的一件事就是下一层会干什么事,比如“将传入编号对应的人员信息设置为离职”,但下一层的代码不一定已经写出来了,所以这会需要有个接口,让写上层代码的人先把代码写下去。
从抽象角度来说,不同业务模块之间的共用,不一定是共用某段代码,也可能是共用某段逻辑框架,这时候就需要抽象一个接口层出来,再通过不同的注入逻辑实现。比如:模块1是登记学生信息,模块2是新闻发布,看上去是不相关,但分析下了,有共同点,顺序都是1.验证是否有权限2.验证输入参数是否合法3.将输入参数转化为业务数据4.数据库存取5.写log,那就可以写一个service接口,里面有个上述5个函数,再分别写2个service实现。具体执行的时候,通过各种注入方法,直接new也好,用spring注入也好,实现不同的效果。
当然上面说的这种情况很少有人这么干了,因为已经普遍到这个程度,再精简就是struts了,javaweb的各种mvc框架都提供机制给你干这个事,但每个项目或产品,都应该用类似的思路抽象出一些东西
这些要搞定,写接口然后实现mock用于测试就随便了