Mechanical Engineer and Process Development Engineer Position available# ChemEng - 化学工程
z*3
1 楼
抛砖引玉
吃饱了看文茜世界财经周报,看得昏昏的想睡,睡觉前赶紧写,写完睡觉去了
这样,先不从dto说起了,说tiers
一个j2ee经典的tiers最早提出来的时候,是三层,所谓的三层说的是sever side三层
不包括client side和database
三层里面分别有一层专门跟以上两个东西打交道
一个是presentation tier,这个跟client side打交道
一个是persistent tier,这个专门跟database打交道
中间还剩下一个叫做business tier,这么三层,这都很熟悉了
那么当初提出这个构想的时候
是基于以下一个方式
client side是applet+browser
presentation tier是servlet+jsp,servlet是controller,jsp是viewer
model需要你自己去提取,去包装
business tier则是ejb,尤其是session bean,stateful和stateless
persistent tier也是ejb,是entity bean
database用jdbc连接
这五个层面都可以放在不同的物理机器上单独运行(至少理论上是这样滴)
不能不说这是一个非常成功的模式,这个模式构建出整个j2ee的基础
到今天所有用的jave ee都是这个模式演变而来的
这种模型的理论依据其实很简单,就是完全配合软件工程里面的各种理论
其中非常强调分工和协作,理论上
client side的applet,presentation tier的servlet, jsp, html, javascript
business tier的ejb,都是分开独立部署的实体,需要各自继承不同的接口
比如appletClass extends japplet
比如servletClass extends httpServlet
比如ejb implements ejbHome
applet的部署是jar,presentation tier的部署是war,然后ejb的部署也是jar
然后war和jar包合在一起可以单独打包成ear
这是理论,但是实际上,ejb往往直接打包成ear
然后再辅助以xml,交给专门的部署人员去部署
同时虚拟机由专门的人员调试,安装,同样的,ejb的调试和安装也应该由专门的人完成
这一批人加上各个tier的开发人员,再加上database的工作人员
理论上,记住了,一个j2ee小组里面,应该有至少 6 个不同职能的工作人员,甚至更多
但是实际上,狗屁~!!!!!!!!!!!!!
经常是一个人从头写到尾,搞不好连database都是这个人在维护
这是其中一个问题
另外一个理论上的致命缺陷是
tier与tier之间的接口,都暂时只能是primitive datatype的
也就是只定义了String, int之类的原始数据类型
那么这一套实际上是有足够的方式支持的
client side -> presentation tier,我们用http和html
presentation tier -> business tier,我们用ejb对rmi的封装,remote接口
business tier->integration tier,还是ejb,还是用remote接口
integration tier->database,用jdbc,jdbc有专门的api
但是实际上,java开发一般方法返回值,很少是这么简单的东东
至少都是一个包装好的java entity bean,也就是我们常见的那个
setter/getter+private variables的普通java bean,下文就统一叫做实体bean了
那么这个时候,每一层之间的通信,都是个问题,就是java的实体bean怎么传递到另外
一层去?
那么这个时候进化,spring跳了出来,说你们不要那么瞎搞了
把中间三层部署在不同的物理机器上是愚蠢的,你们没有必要这么干
因为大多数时候,这些东西都是在一个机器上运行的
所以你们不用去搞ejb那么麻烦的东西,听我的,按照我说的做
于是痛恨ejb+学不会ejb的人们就赶紧转向spring了
同时在另外两个层面,也分别出现了其他的框架
这就是当时非常流行的struts和hibernate
struts是presentation tier的框架,这个框架的好处其实是帮你自动封装model到实体
beans中去
写过struts的人都记得那个private + setter/getter的年代
另外一个就是hibernate,实现了object-relational-mapping的同时
对不同数据库之间的差异实现了统一接口
这就是那个时候最流行的ssh框架,struts+spring+hibernate
到了这个时候,sever side的三个tiers分别对各自的tier实现了实体bean的封装
但是在不同层次的实体bean之间的转换还是一个大问题
继续进化,spring开始统一struts
因为在同一台虚拟机上,在不同层面搞出不同的实体bean有意义么?
聪明的人开始想到了,发明了一个dto设计模式,data transfer object
这个模式的特点就是在不同的tiers之间传递相同的dto
这个dto就是前面说的实体bean,只不过有一个约定俗成就是
无论struts还是spring还是hibernate,都用这个实体bean
然后struts封装好form扔过来的数据,塞给spring,spring再拿到hibernate的
sessionfactory
塞到database里面去,一捅到底,湿得一塌糊涂,然后查找的时候再从database里面拔
出来
然后修改完再查进去,再拔出来,再插进去……
后来spring觉得老搞这个太无聊了,于是开始搞spring mvc,大获成功
同时struts自宫了一把,升级到2.0版本之后居然跟1.0版本相去甚远,群众表示很难接
受新尺度
于是spring利用其在business tier的优势渗透到presentation tier,逐渐取代了
struts
并且积极配合hibernate的sessionfactory,封装出了spring的sessionfactory
就这么着,一统中间三层,成为最流行的框架
但是这么做湿有问题的,就是dto的存在,使得所有的框架,对dto都产生了依赖
那么这些dto就像一条又一条的锁链,把中间三层给捆了起来
使得中间三层的耦合度骤然增加,软件工程里面对于模块划分的建议是
耦合度越低越好,内聚性越高越好,你倒好,用一群dto,把所有的tiers全部捆了起来
这么做,在一台虚拟机上,不会有太大问题,但是如果是不同的机器呢?
你要保证不同的机器上都有相同的类,这个就很明显是一个严重的问题
那怎么办?
其实ejb做过尝试,就是提供entity bean的remote接口
就是不仅提供方法的接口,还提供实体bean的远程接口
但是群众完全不能接收,遂被迫deprecate ejb里面的entity bean
其实今天回过头去看,会发现ejb其实远走在时代的前面
只不过群众永远都是不能理解复杂的东西
后面说到的web service也差不多,当然这也跟定义的人不考虑群众感受有关
他们总是想把所有情况都考虑进去,但是当一种相对简单的情况就能解决大部分问题的
时候
群众会抛弃那种繁琐复杂的方式,而去选择那种相对简单的解决方案
但是时间一久,群众又会觉得相对简单的方式不够用,又会寻求额外的补充
那么这个时候原先复杂的定义就会跟这种相对简单的解决方案做一个妥协
折中出来一个理想状态,ejb3.0和rest就是这么一种妥协的产物
替代原先的ejb2.0和soap
回头,看看其他层是怎么做的再说,前面说了,从client side开始到database
其实除了中间三层,还有另外两层,一里一外,也就是浏览器和数据库是怎么跟java互
动的?
很简单,协议,浏览器通过http协议定义传输格式,同时默认html为返回text的语言
数据库则是通过sql来查询,同时返回一个resultset
那么不管是http,html还是sql,都是一种协议,约定,契约,所有人都遵守的契约
那既然在不同的软件之间可以有这种契约,为什么java自己内部不遵守契约呢?
这个时候搞出了一个东西叫做xml,xml是html的延伸,但是远比html要规范
同时要容易扩展,可以扩展成任何一种语言,并用这种语言定义数据格式
最常见的一个应用就是把xml扩展成为xhtml,尽量在语法上贴近html
但是它是xml,同时用xhtml来取代html,成为client side跟presentation tier的默认
交流语言
这是第一步,同时hibernate完成了对sql的封装也完成了对数据库的映射
因为做得是如此之好,所以被邀请去搞jpa规范,这是第二步
当这两步都实现了之后,其实服务器软件对于数据库和浏览器的整合已经接近完成
也就是第一层和最后一层跟中间层的通信都已经逐步稳定规范下来了
那么唯一要处理的就是,如何规范,presentation tier和business tier之间的通信?
这个时候诞生了一个东西叫做web service
web service本意是暴露web层服务的
所以一开始搞得尤其复杂,uddi, wsdl和soap,那么现在回头看
uddi已经基本上可以说是失败了,soap也快玩完了
因为soap要求发送request的时候也用xml封装,吃饱了撑着
有一个人借鉴了client side跟presentation tier的通信方式
发明了了一个叫做rest的东西,尽可能复用了http协议
用一个类似client side发送http request一样的东西,发送web service的request
同时像client side接收html一样接收xml文件
同时把这一套应用到presentation tier和business tier之间
你会陡然发现,我乐个去,这两层之间的通信原来跟前面那两层的通信是如此的相似
所以ejb2.1之后很快就把web service给加到ejb规范里面去了
同时通过web service,使得ejb暴露接口给php等其他web服务变得可行
又同时ejb因为遵循了jpa规范,使得hibernate一样的orm在所有的ejb容器提供商中
成为一个硬性要求,就是你必须提供这种东西,否则不发执照给你
所以ejb的位置越来越清晰,就是成为一个完全的中间件,回到它本来的位置
它本来就应该做的那个角色,同时打算用esb对这两层的通信做一个消息面的优化
类似跟数据库连接时候搞的connection pool一样的东西
不过实现起来这两个又有太大的区别,而且esb现在也只是一个概念
包括web service,ejb现在也只支持到wsdl1.0,wsdl2.0也还没有完全支持
但是这是一个远景,应该是可以预期的
这个问题一旦解决,所有层与层之间的通信将会被完全规范化
使得真正的层与层之间的低耦合,高内聚,不互相依赖的模型成为现实
不再像以前一样,被一堆dto捆住了所有tiers,使得真正的分工和协作成为可能
所以现在已经出现了front end和back end的招工广告,其实就在预示着这种走势
front end对应的就是presentation tier吧
back end对应的就是ejb对应的business tier和integration tier吧
不过新版本的ejb已经去掉integration tier的内容,完全仍给jpa了
但是不管是ejb还是jpa,这都是java ee5,6,以及以后版本的组成部分
只要是java ee容器,这几个都是必须实现的,标准要遵守
说了这么多,不知道理解没有,下面通过一个实例来具体说说spring和ejb的区别
吃饱了看文茜世界财经周报,看得昏昏的想睡,睡觉前赶紧写,写完睡觉去了
这样,先不从dto说起了,说tiers
一个j2ee经典的tiers最早提出来的时候,是三层,所谓的三层说的是sever side三层
不包括client side和database
三层里面分别有一层专门跟以上两个东西打交道
一个是presentation tier,这个跟client side打交道
一个是persistent tier,这个专门跟database打交道
中间还剩下一个叫做business tier,这么三层,这都很熟悉了
那么当初提出这个构想的时候
是基于以下一个方式
client side是applet+browser
presentation tier是servlet+jsp,servlet是controller,jsp是viewer
model需要你自己去提取,去包装
business tier则是ejb,尤其是session bean,stateful和stateless
persistent tier也是ejb,是entity bean
database用jdbc连接
这五个层面都可以放在不同的物理机器上单独运行(至少理论上是这样滴)
不能不说这是一个非常成功的模式,这个模式构建出整个j2ee的基础
到今天所有用的jave ee都是这个模式演变而来的
这种模型的理论依据其实很简单,就是完全配合软件工程里面的各种理论
其中非常强调分工和协作,理论上
client side的applet,presentation tier的servlet, jsp, html, javascript
business tier的ejb,都是分开独立部署的实体,需要各自继承不同的接口
比如appletClass extends japplet
比如servletClass extends httpServlet
比如ejb implements ejbHome
applet的部署是jar,presentation tier的部署是war,然后ejb的部署也是jar
然后war和jar包合在一起可以单独打包成ear
这是理论,但是实际上,ejb往往直接打包成ear
然后再辅助以xml,交给专门的部署人员去部署
同时虚拟机由专门的人员调试,安装,同样的,ejb的调试和安装也应该由专门的人完成
这一批人加上各个tier的开发人员,再加上database的工作人员
理论上,记住了,一个j2ee小组里面,应该有至少 6 个不同职能的工作人员,甚至更多
但是实际上,狗屁~!!!!!!!!!!!!!
经常是一个人从头写到尾,搞不好连database都是这个人在维护
这是其中一个问题
另外一个理论上的致命缺陷是
tier与tier之间的接口,都暂时只能是primitive datatype的
也就是只定义了String, int之类的原始数据类型
那么这一套实际上是有足够的方式支持的
client side -> presentation tier,我们用http和html
presentation tier -> business tier,我们用ejb对rmi的封装,remote接口
business tier->integration tier,还是ejb,还是用remote接口
integration tier->database,用jdbc,jdbc有专门的api
但是实际上,java开发一般方法返回值,很少是这么简单的东东
至少都是一个包装好的java entity bean,也就是我们常见的那个
setter/getter+private variables的普通java bean,下文就统一叫做实体bean了
那么这个时候,每一层之间的通信,都是个问题,就是java的实体bean怎么传递到另外
一层去?
那么这个时候进化,spring跳了出来,说你们不要那么瞎搞了
把中间三层部署在不同的物理机器上是愚蠢的,你们没有必要这么干
因为大多数时候,这些东西都是在一个机器上运行的
所以你们不用去搞ejb那么麻烦的东西,听我的,按照我说的做
于是痛恨ejb+学不会ejb的人们就赶紧转向spring了
同时在另外两个层面,也分别出现了其他的框架
这就是当时非常流行的struts和hibernate
struts是presentation tier的框架,这个框架的好处其实是帮你自动封装model到实体
beans中去
写过struts的人都记得那个private + setter/getter的年代
另外一个就是hibernate,实现了object-relational-mapping的同时
对不同数据库之间的差异实现了统一接口
这就是那个时候最流行的ssh框架,struts+spring+hibernate
到了这个时候,sever side的三个tiers分别对各自的tier实现了实体bean的封装
但是在不同层次的实体bean之间的转换还是一个大问题
继续进化,spring开始统一struts
因为在同一台虚拟机上,在不同层面搞出不同的实体bean有意义么?
聪明的人开始想到了,发明了一个dto设计模式,data transfer object
这个模式的特点就是在不同的tiers之间传递相同的dto
这个dto就是前面说的实体bean,只不过有一个约定俗成就是
无论struts还是spring还是hibernate,都用这个实体bean
然后struts封装好form扔过来的数据,塞给spring,spring再拿到hibernate的
sessionfactory
塞到database里面去,一捅到底,湿得一塌糊涂,然后查找的时候再从database里面拔
出来
然后修改完再查进去,再拔出来,再插进去……
后来spring觉得老搞这个太无聊了,于是开始搞spring mvc,大获成功
同时struts自宫了一把,升级到2.0版本之后居然跟1.0版本相去甚远,群众表示很难接
受新尺度
于是spring利用其在business tier的优势渗透到presentation tier,逐渐取代了
struts
并且积极配合hibernate的sessionfactory,封装出了spring的sessionfactory
就这么着,一统中间三层,成为最流行的框架
但是这么做湿有问题的,就是dto的存在,使得所有的框架,对dto都产生了依赖
那么这些dto就像一条又一条的锁链,把中间三层给捆了起来
使得中间三层的耦合度骤然增加,软件工程里面对于模块划分的建议是
耦合度越低越好,内聚性越高越好,你倒好,用一群dto,把所有的tiers全部捆了起来
这么做,在一台虚拟机上,不会有太大问题,但是如果是不同的机器呢?
你要保证不同的机器上都有相同的类,这个就很明显是一个严重的问题
那怎么办?
其实ejb做过尝试,就是提供entity bean的remote接口
就是不仅提供方法的接口,还提供实体bean的远程接口
但是群众完全不能接收,遂被迫deprecate ejb里面的entity bean
其实今天回过头去看,会发现ejb其实远走在时代的前面
只不过群众永远都是不能理解复杂的东西
后面说到的web service也差不多,当然这也跟定义的人不考虑群众感受有关
他们总是想把所有情况都考虑进去,但是当一种相对简单的情况就能解决大部分问题的
时候
群众会抛弃那种繁琐复杂的方式,而去选择那种相对简单的解决方案
但是时间一久,群众又会觉得相对简单的方式不够用,又会寻求额外的补充
那么这个时候原先复杂的定义就会跟这种相对简单的解决方案做一个妥协
折中出来一个理想状态,ejb3.0和rest就是这么一种妥协的产物
替代原先的ejb2.0和soap
回头,看看其他层是怎么做的再说,前面说了,从client side开始到database
其实除了中间三层,还有另外两层,一里一外,也就是浏览器和数据库是怎么跟java互
动的?
很简单,协议,浏览器通过http协议定义传输格式,同时默认html为返回text的语言
数据库则是通过sql来查询,同时返回一个resultset
那么不管是http,html还是sql,都是一种协议,约定,契约,所有人都遵守的契约
那既然在不同的软件之间可以有这种契约,为什么java自己内部不遵守契约呢?
这个时候搞出了一个东西叫做xml,xml是html的延伸,但是远比html要规范
同时要容易扩展,可以扩展成任何一种语言,并用这种语言定义数据格式
最常见的一个应用就是把xml扩展成为xhtml,尽量在语法上贴近html
但是它是xml,同时用xhtml来取代html,成为client side跟presentation tier的默认
交流语言
这是第一步,同时hibernate完成了对sql的封装也完成了对数据库的映射
因为做得是如此之好,所以被邀请去搞jpa规范,这是第二步
当这两步都实现了之后,其实服务器软件对于数据库和浏览器的整合已经接近完成
也就是第一层和最后一层跟中间层的通信都已经逐步稳定规范下来了
那么唯一要处理的就是,如何规范,presentation tier和business tier之间的通信?
这个时候诞生了一个东西叫做web service
web service本意是暴露web层服务的
所以一开始搞得尤其复杂,uddi, wsdl和soap,那么现在回头看
uddi已经基本上可以说是失败了,soap也快玩完了
因为soap要求发送request的时候也用xml封装,吃饱了撑着
有一个人借鉴了client side跟presentation tier的通信方式
发明了了一个叫做rest的东西,尽可能复用了http协议
用一个类似client side发送http request一样的东西,发送web service的request
同时像client side接收html一样接收xml文件
同时把这一套应用到presentation tier和business tier之间
你会陡然发现,我乐个去,这两层之间的通信原来跟前面那两层的通信是如此的相似
所以ejb2.1之后很快就把web service给加到ejb规范里面去了
同时通过web service,使得ejb暴露接口给php等其他web服务变得可行
又同时ejb因为遵循了jpa规范,使得hibernate一样的orm在所有的ejb容器提供商中
成为一个硬性要求,就是你必须提供这种东西,否则不发执照给你
所以ejb的位置越来越清晰,就是成为一个完全的中间件,回到它本来的位置
它本来就应该做的那个角色,同时打算用esb对这两层的通信做一个消息面的优化
类似跟数据库连接时候搞的connection pool一样的东西
不过实现起来这两个又有太大的区别,而且esb现在也只是一个概念
包括web service,ejb现在也只支持到wsdl1.0,wsdl2.0也还没有完全支持
但是这是一个远景,应该是可以预期的
这个问题一旦解决,所有层与层之间的通信将会被完全规范化
使得真正的层与层之间的低耦合,高内聚,不互相依赖的模型成为现实
不再像以前一样,被一堆dto捆住了所有tiers,使得真正的分工和协作成为可能
所以现在已经出现了front end和back end的招工广告,其实就在预示着这种走势
front end对应的就是presentation tier吧
back end对应的就是ejb对应的business tier和integration tier吧
不过新版本的ejb已经去掉integration tier的内容,完全仍给jpa了
但是不管是ejb还是jpa,这都是java ee5,6,以及以后版本的组成部分
只要是java ee容器,这几个都是必须实现的,标准要遵守
说了这么多,不知道理解没有,下面通过一个实例来具体说说spring和ejb的区别