J2EE设计师之路

原创 2007年09月27日 11:39:00

J2EE设计师之路

FiliRon

,  序言:

在阅读本文之前,我们首先想想:如果我们要开发一个软件产品或开发一个程序,首先要做的是什么?

当然,首先要解决的就是科学论证解决方案,在程序开发前,要有一个好的架构来支撑和一个业务开发方向。一个好的开发框架可以带来开发时的高效率,而一个好的明晰的业务思路可以带来更少的需求变动。

当然有人认为开发框架是高级架构师的事,业务思路是业务专家的活,我们不需考虑这些。确实如果你准备一辈子当个小兵,那么这些无关紧要。然而如果你有鸿鹄之志,你在开发时就要关心这些。当然,这篇文章暂时不涉及到对业务理解方面的内容,只是说说架构,但我们不能忽视业务。

一个好的架构是成功的一半,我们不能靠一次一次的尝试来编程开发,那样即耗费时间、金钱、人力,又效率不高。这就像工业革命以前发明新产品一样,人们凭借经验生产,然后产生技术,最后形成科学的过程,这在工业革命时便被推翻了.要反过来做,先科学论证,再产生技术,然后生产产品。伟大的发明家瓦特便是在推翻这样一个流程的基础上发明新式蒸汽机,其实蒸汽机在瓦特发明之前就已经被人们发明了,可是由于耗能巨大且只能用煤矿来支持所以没有得到推广.瓦特则没有走发明的老路,他先通过学习数学、物理、化学,然后论证公式成功后再发明蒸汽机,这样产生的新式的蒸汽机即高效又实用便捷,这个发明以后影响了人们的生活方式,带来里技术变革和飞跃。两种思维方式会带来两个极端,就是闭门造车和瞎子摸象。而实践论认为:从实践提升到理论,再由理论指导实践,事物由此向前发展。我们在从编码工程师到达系统分析师,再到系统架构师的路途中有很多困难。我们既要做最简单重复的事情,也要学习瓦特精神,理论和实践相结合

个好的开发框架是轻量、简洁、高效.一般来说,一个应用中简单重复的东西占80%,复杂特殊的东西占20%。一个框架的开发效率,就在于这个80%简单 与 20%复杂之间的平衡。假如,不用框架来开发,简单的80%要消耗 80个资源数,复杂的20%要消耗20个资源数,总资源数是100;使用了某个框架,简单的80%只要消耗10个资源数,复杂的20%要消耗40个资源数,总资源数是50。那么,我们说,这个开发框架是有效率的。有人说用EJBO/R等都要消耗大量资源。我们应该同时应对复杂和简单。当然,为了应对复杂,简单的东西可能就应对得不那么好。比如,做这样一个开发框架,简单的80%要消耗20个资源数,复杂的20%要消耗10个资源数,总资源数是30。 这种开发框架是有可能实现的。而且是很有意义的。尤其是在复杂部分的比例提高的时候。越复杂的系统,这种开发框架就越有意义。

同样,我们在开发程序时也要明白和重视我们的开发框架的原理,这样才能更加迅速的开发。当然我们没有公司的框架的源代码,有人说这样分析好比海底捞针。我认为不会,因为源代码只是产品或者是技术,可是框架是科学。科学是可以发现和挖掘的。所以我觉得告诉大家框架的原理是十分重要的,对于加快技术完善和提高效率大有裨益的。反而如果一味的让程序员开发那只是在降低效率。这就好比计划经济和市场经济一样,如果我们让大家分享工作和结果,那么我们的产出不会巨大,而且也是相当消极的。而如果我们告诉大家我们,每个人都要为自己的利益努力,那么人都是主动的,产出也是巨大的。这就是看不见的手的功效。所以我建议我们要让大家都能理解框架甚至研究框架。那么我们的收获肯定是巨大的。

首先说明一下本人也是在不断学习中总结的这些,有些地方杂而不精,希望大家多给指点。3q

 

二,思考问题:

我们要研究框架,首先要明白自己疑惑什么:

J2EE是什么?我们要使用架构,架构的目的是什么了?我们频繁的使用Struts,但它帮我们解决什么呢?到底要不要使用EJB了?

找到这些疑问,我们便可以开始解决这些疑问了。

整篇文章的结构大致如下:

首先我们要明白公司的框架是基于J2EE的解决方案,那么我们就必须明白J2EE的意义和功效。所以我们首先要了解什么是J2EE,什么是架构。

其次,将J2EE中各组件和各架构有机的结合起来并解藕的是Struts框架,我们要明白Struts是如何做到这一点。

然后,在J2EE中最重要的就是EJB的实现。我们要明白EJB的流程和规范。

介绍完基本的框架组件了,我们再了解一些基本概念。

最后,我们将详细分析框架中的每一层的原理。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

三,理解J2EE和架构:

1J2EE产生的背景

在说明J2EE是什么之前,先描述一下它出现的背景:

企业应用系统复杂度越来越高,在性能和安全性方面要求也到了空前的地步。应用开发商的成本和响应时间成级数上升。很多公司开发了自己的中间件以降低称本,缩短响应时间,但是各个公司的不同的中间件不能组装在一起形成服务。

在这样的背景下,SUN公司提出了J2EE(企业版 java 平台 ),它是一个解决方案,一个能够构建复杂企业应用并能满足扩展性、性能、安全性的java解决方案SUN提出J2EE目标很明确:
1.
满足企业应用的高要求

2.
降低开发商的成本
3.
减少开发商的响应时间

为了实现上述目标,SUNJ2EE方案进行了定义(即J2EE规范),在J2EE1.4采用了分层体系,提出了容器和构件的概念,并明确了容器的职责、构件的职责及如何一齐协调运作,它在其中运用了JSPXMLEJBJTAJDBC13种技术。

无可非议,该解决方案能够迎合企业应用的高要求、高复杂度。所以该解决方案得到了广泛的认可,形成了潮流,出现了中间件开发和构件开发的概念。

中间件开发商按照J2EE规范进行容器开发,如WEBSPHERE WEBLOGIC JBOSS,构件开发商按J2EE规范专心开发业务构件,然后部署到中间件中形成应用。

2,理解J2EE

清楚了J2EE产生的背景,我们要具体明白什么是J2EE.

我的理解是:J2EE是一个多层、分布式、基于组件的、企业级、应用模型。

1,多层指的是将框架进行解耦,相互独立。最常见的是MVC三层架构。他为系统提供了伸缩性的特点:让web服务器负责提供页面,应用服务器处理应用逻辑,数据库服务器提供数据服务。我们一般将系统分为三层,表示层,业务层,持久层。如果要分得更细的话,可以分为客户层,交互层,应用层,业务逻辑层,资源访问层,资源层。

客户层可以再分为:页面层(HTML, JavaScript, CSS等页面资源)和页面模板层(JSP, Freemarker, Velocity, XSLfastm等,用来生成HTML, JavaScript, CSS等页面资源)。

表示层

业务层

持久层

客户层

交互层

应用层

业务逻辑层

资源访问层

资源层

浏览器

GUI客户端

Web容器/适配器

FrantControl

RequestProcesser

Command

viewDispater

EJB容器

AppControl

sessionFacade

CICS

EJB容器

客户模型

个税模型

其他业务

领域模型

EJB容器

DAO

Mail

Message

OtherConnector

RDBMS

Mailserver

Message

Other

àHTTPS

àRMI(远程方法调用)

àJDBC

àJMS

àJAVAMAIL

解决方案:最佳实践一或者最佳实践二

最佳实践一(jxfaster/html+command+logic+dao

最佳实践二(struts/jsp+command+logic+dao

 

2,分布式指的是:一个或多个业务逻辑的执行可以在多个终端进行处理。

解决方案:EJB和集群

 

3,基于组件指的是:组件化编程(基于接口的程序开发)。程序开发要面临两个问题:组件升级和系统部署,使用组件化编程可以很好的解决上面两个问题。

解决方案:使用EJB EJB通过JDNI(目录服务)在网络中查找分布式组件

组件服务商à应用服务商à系统部署员à系统管理员

                           ^

                           |

EJB容器/服务器供应商

服务端组件体系结构方案:

Mircrosoft

COM+

Sun

J2EE

OMGobject Management Group

CORBA 公共对象请求代理结构

 

4,企业级指的是:大型应用解决方案。

解决方案:J2EE或者.Net,J2EE基本上是将解决方案的规范告诉,至于具体分层和实现都由开发人员去解决。这样就造成大量的开源框架出现。而.net则大量封装,不仅封装底层有时页面展现都是拖动组件。在soa即将盛行的时,个人感觉J2EE的优势将超过.net,毕竟在面向服务的实现上J2EE更加快捷。

5,应用模型指的是:模型我们一般用于模拟一个真实的系统。建立模型最主要的目的是帮助理解、描述或模拟真实世界中目标系统的运转机制。在软件开发领域,模型用来表示真实世界的实体。在软件开发的不同阶段,需要为目标系统创建不同类型的模型。在分析阶段,需要创建概念模型。在设计阶段,需要创建设计模型。J2EE便是一个系统解决方案实体。

解决方案:可以采用面向对象建模语言UML来描述模型。

3,什么是架构

明白了J2EE,我们要问架构是什么?架构的目的是什么?

引用jdon的板桥的一句话:

架构是就软件平台的搭建和设计规划,目的是实现软件最大的可维护性和可拓展性延续软件的生命,就象人生下来,整个架构都有了,虽然一些器官不能用到(例如生殖器官),但是一生下来还是有这些器官,这就是架构设计的优势,没有架构设计的软件是看不到明天,生下的小孩就不会有生殖器官,因为他认为小孩不需要,但是他没有看到小孩20岁以后的未来。

好的框架甚至只需要XML配置就可以,这样,OO能力差一些人,就不需很多编程,而只需配置配置XML就可以,这样,通过架构设计,可以充分发挥现有人员的长处,克服他们的短处。

衡量J2EE应用系统设计开发水平高低的标准就是:解耦性;你的应用系统各个功能是否能够彻底脱离?是否不相互依赖,也只有这样,才能体现可维护性、可拓展性的软件设计目标。

架构设计架构时需要思考的三个方向。分别为:面向对象、面向方面、面向服务。这三个维度可以看作是正交的,但不同维度会互相印证,互相支撑。

一、面向对象

面向对象提出有三个主要目标:重用性、灵活性和扩展性,强调对象的抽象封装继承多态。它能让人们以更加接近于现实世界的方式来思考程序,这点可以说是面向对象最大的进步。

二、面向方面

面向方面最初来源于hook技术,本质上就是满足扩展的需求,可以在程序中自由扩展功能。

面向方面不仅仅是一门编程技术,同样也是一种架构设计的思路。如果说OO是纵向地分析、切割整个系统,那么可以认为AOP是横向地对系统作切片。简单地理解,OOAOP分别从两个不同的角度给我们提供了分析系统的思路。面向方面可以弥补面向对象的缺陷,两种方式有机的结合在一起可以更加有效地分析系统。

我们认为OO是接近于人类认识自然的思维方式,但对于东方来说却并不是这样。当西方人看到一个复杂系统的时候,只会有一种思路,就是分解”——将系统分解成一块一块,然后每个部分作研究。当东方人看到一个复杂系统的时候,更多地会关注系统中存在的关系,将系统作为一个有机的整体进行研究。

这两种思维方式都没有问题,结合起来的话分析问题解决问题会更好。面向对象与面向方面也同样如此,都能对应到人类认识自然的思维方式上。

三、面向服务

面向服务可以说是最近炒得比较火的概念了。包括现在提到的SaaS——Software as a service,软件即服务。准确说来,面向服务不仅仅是软件行业的概念。这个要从社会的产业结构说起。

社会产业总共分为三个,第一产业农业,第二产业工业,第三产业服务业。最早社会的主要产业是第一产业农业,将近有几万年的历史。十八世纪下半叶在英国开始的工业革命,对人们的生活产生了根本性的影响,社会的主要产业成了第二产业工业。

现在仍然属于工业时代,或者有人说的后工业时代。而在后工业时代,社会的经济体制必定要向第三产业服务业逐渐转型。面向服务其实是社会经济体制重心的一种迁移。

还是说回到软件行业,社会的主要产业将转变成服务业,自然软件行业也会出现对应的变化,那就是这里提到的面向服务。面向服务今后会影响到软件的交付模式,会对整个软件行业的体制产生影响。

而说到架构层面,面向服务是系统发布功能的一种方式。并且基于这种方式下不同的系统之间能有效地通信、协作。常见的实现技术就是Web Service

面向方面的思想提出来能够弥补面向对象的缺陷。面向对象的方式不能实现横切关注点的分离,而面向方面正是为了解决这个问题。面向方面与面向对象一样都是解决系统内部结构的设计。

面向服务更多的是涉及到系统的外部,简单地说就是发布功能。它并不关注系统内部结构的实现,所以说面向服务与面向对象或者面向方面并不冲突。

这三个维度并不是绝对孤立的,它们之间会互相影响、制约。我们在分析架构的时候需要同时考虑到这三个维度的问题。这样有助于我们设计出更加优秀的架构。 

 

四,理解Struts:

Web表现层之下的所有层次——O/R层、业务层、Web Framework等都直接由Java代码实现,都能够很好的结构化,对象化,不存在任何问题。唯独Web表现层,天生结构松散,野性难驯。使用Struts就是为了解决这个问题。

1Struts的三个组件

Struts主要包括三个组件:

·ActionServlet组件:充当Struts框架的中央控制器。

·RequestProcessor组件:充当每个子应用模块的请求处理器。

·Action组件:负责处理一项具体的业务。

Struts框架采用ActionServletRequestProcessor组件进行集中控制,并采用Action组件来处理单项业务。

ActionServletStruts框架的唯一个Servlet,它的责任是处理所有的请求。只要它收到了一个请求,它就试图找到一个子系统来处理这个请求。ActionServlet实例接受到HTTP请求之后,在doGet()doPost()方法都会调用process()方法来处理请求。以下是ActionServletprocess()方法的源代码:

protected void process (HttpServletRequest request, HttpServletResponse response)

throwIOException, ServletException

{

 ModuleUtils.getInstance().selectModule(request,getServletContext());

getRequestProcessor(getModuleConfig(request)).process(request,response);

}

 

process()方法中,首先调用org.apache.struts.util.ModuleUtils类的selectModule()方法,这个方法选择负责处理当前请求的子应用模块,然后把与子应用模块相关的ModuleConfigMessageResources对象存储倒request范围中,这使得框架的其余组件可以方便地从request范围中读取这些对象,从而获取应用配置信息和消息资源。

process()方法的第二步操作为获得RequestProcessor类的实例,然后调用RequestProcessor类的process()方法,来完成预处理请求操作。一旦找到了这个子系统,它就为那个字系统产生一个RequestProcessor 对象,并且通过传递HttpServletRequest 对象和HttpServletResponse 对象来调用RequestProcessor 对象的process()方法。

RequestProcessor.process() 方法是大多数请求被处理的地方。process()通过应用模板方法模式来实现,在这个方法里,处理请求的每一个阶段都被作为一个独立的方法,所有这些方法都在process()方法里被顺序调用。

下图就是Struts的流程图:

(Struts应用的生命周期中,只会为每个Action类创建一个实例,所有的客户请求共享这个实例,以保证线程安全。在Struts2这里有所改变,可以创建多个Action类实例,因为采用了IOC模式)

2Struts扩展

你可以使用下面三种方法来扩展Struts
    1.插件:如果你希望在系统启动的时候和关闭的时候处理一些商务逻辑,实现你自己的插件类吧。
    2.RequestProcessor
:在请求处理阶段,如果你想在某个特定的功能点处理一些商务逻辑,实现你自己的RequestProcessor吧。例如,你可以扩展RequestProcessor来检测用户是否登陆,或者在处理每一个请求之前检测用户是否有处理一些特殊行为的角色。
    3.ActionServlet
:如果你想在请求处理阶段或者系统启动、关闭的时候处理一些特殊的商务逻辑,你可以扩展ActionServlet类。但是你只能在当扩展插件和扩展RequestProcessor都不能满足你的要求时候使用。

比如我们要在系统的启动或关闭阶段做一些事情:装载权限系统和其他层框架等等.我们就使用了ActionServlet来装载的. 两个最为成功的例子是Struts Validation框架和Tiles框架。具体做法以后介绍.

这里值得注意的是:你可以创建一个ActionServlet 的子类来处理你在应用的开始、结束或每一个请求所要处理的事情。但是你最好创建一个插件或一个RequestProcessor ,而不是ActionServlet的子类。Servlet 1.1以前,Tiles框架是通过扩展ActionServlet 来装配输出;但是从1.1以后,它使用TilesRequestProcessor 类。(为什么?稍后分析)

关于Struts的重要性, 还是必须从程序代码可维护性来讲,也就是从OO角度讲,Struts能够通过MVC模式将表现层进行细分,实现表现层内部各个细分部分的最大解耦,Struts也可以将页面离散无规律的数据转变为对象,供业务层服务,也就是Struts表现层实际是业务层的服务者,为其提供对象化的枪支弹药,而业务层则可以围绕这些对象实现对象化编程,从而实现更好的可维护性.当然持久层不用说,和表现层一样也是业务层的服务者,为其提供对象化的枪支弹药,不过这些对象是从数据库里拿来的,是从一个非对象化,离散的、关系型的数据库拿来的,Hibernate等框架必须将他们转为对象,给业务层使用。

表现层---- 抽象为对象---à业务层ß----抽象为对象---持久层

表现层和持久层这种配置工作就如同打包邮寄一样:你首先要将你的单件用一个箱子包装起来,达到目的地,这个箱子被打开,单件被逐步取出。表现层和持久层这样做的目的是保证中间业务层完全面向对象,保证业务层完全是和一个个对象模型打交道。

在一个真正面向对象的系统中,表现层和持久层是为了将非对象化的数据转为对象。因此,在先进的JavaEE/J2EE架构中,表现层和持久层的主要工作就是配置工作,而且主要是映射mapping的配置。

下面的问题就是:如何解决映射配置简单而且易用,如果拥有正确的指导配置的思维,那么配置工作就容易简单多,否则,就倍感配置复杂。当我们第一次接触这种配置式开发时,我们也感觉复杂和麻烦,那是因为我们没有完整的OO思维。

五,理解EJB:

EJB不是产品是一种规范,软件产商根据它来实现EJB服务器。我们可以将EJB理解为专门做服务端组件的规范。

EJB为我们提供一个标准的分布的、基于 OO 的组件架构,并屏蔽复杂的系统级功能需求

我们可以想像EJB是插在程序界面后的USB,可以运行这个usb上的程序或者查看上面的数据信息,而且是即插即拔的,而我们不需要知道他们真正通过什么协议建立起的连接或者怎么运行它上面的程序的。我们只需提供服务:业务逻辑(session EJBS)和数据访问(Entity EJBS ADO)。

1,什么情况用什么bean

会话bean

提供一定服务

有状态会话beanà处理多个请求(购物车)

Javax.ejb.sessionbean

无状态会话beanà单一请求(信用卡)

实体bean

代表数据对象

BMPBean管理持久性)

Javax.ejb.entilybean

CMP(容器管理持久性)

消息驱动Bean(MDB)

通过允许容器去聚合并且管理消息驱动Bean实例,以此来提供传入JMS消息的并发处理

 

Session Bean用于实现业务逻辑,它可以是有状态的,也可以是无状态的。每当客户端请求时,容器就会选择一个Session Bean来为客户端服务。Session Bean可以直接访问数据库,但更多时候,它会通过Entity Bean实现数据访问。

Entity Bean是域模型对象,用于实现O/R映射,负责将数据库中的表记录映射为内存中的Entity对象,事实上,创建一个Entity Bean对象相当于新建一条记录,删除一个Entity Bean会同时从数据库中删除对应记录,修改一个Entity Bean时,容器会自动将Entity Bean的状态和数据库同步。

MessageDriven BeanEJB2.0中引入的新的企业Bean,它基于JMS消息,只能接收客户端发送的JMS消息然后处理。MDB实际上是一个异步的无状态Session Bean,客户端调用MDB后无需等待,立刻返回,MDB将异步处理客户请求。这适合于需要异步处理请求的场合,比如订单处理,这样就能避免客户端长时间的等待一个方法调用直到返回结果(类似表示层的Ajax)

调用一个EJB组件要比调用一个JavaBean麻烦些,由于EJB组件可以分布在多台服务器上,因此必须首先获得远程或本地Home接口,然后使用Home接口创建EJB之后就可以调用EJB的方法了。

 

举例:

在电子购物中:

由多个购物篮条目(Cart Line Item)组成的一个购物篮(Cart)为一个顾客 (Customer)存储产品的临时选择;由多个订单条目(Order line Item)组成的一个订单(Order)为一个顾客存储产品的永久选择。购物篮能将自身转换为订单。

一个购物篮条目代表一个产品(Product)的临时选择,一个订单条目代表一个产品的永久选择。

估价器(Pricer)在顾客查看购物篮时计算购物篮的价格,并且在顾客最终生成订单时计算订单的价格。

订单处理器(Order Processor)为订单验证信用卡,发送E-mail确认,并标识为永久。

同时从本图中也可以了解一个电子购物的过程:首先,在购物时顾客把自己感兴趣的产品放入购物篮中,同时由估价器对购物篮进行及时估价。然后,顾客在确认购买后,购物篮能自动生成订单。再由估价器计算出订单的价格。接着,由订单处理器验证顾客信用卡的合法性,在交易完成后为顾客发送E-mail确认交易成功,并将本交易标识为永久。

顾客、订单、产品、订单条目这几个对象是永久性、持续性对象,例如,顾客信息、产品信息都需要存入数据库,并且在适当的时候从数据库中读取。所以,这几项都需要用实体Bean来实现。

购物篮和购物篮条目只在顾客购物的过程中起作用,所以不是永久性的,而且每一个购物篮都对应于一个特定的顾客,对应于若干条特定的购物车条目,因此购物篮和购物篮条目用状态会话Bean来充当最合适不过。

估价器的作用是计算出购物篮和订单的价格,它并没有和特定的顾客绑定,可以作用于任意的购物篮,而且也不是永久对象,因此估价器可以用一个无状态会话Bean来充当。

订单处理器是一个特殊的对象,它通过顾客所要求的不同的付款方式产生不同的订单,也就是说,它是由不同的付款方式来驱动的。所以在这里用消息驱动Bean是最恰当的。

 

Home接口

扩展javax.ejb.ejbHome

Remote接口

扩展javax.ejb.ejbObject

 

Enterprise Bean类不具有网络功能,图中的EJB ObjectEJB对象)就是在EJB容器中有网络功能的结构。Ejb对象起着delegate(代理)的作用.实际上是EJB Object触发方法被EJB容器截获,传递给bean实例。EJB对象通过remote接口克隆bean类暴露的每个商务方法。

 

过程步骤:

首先客户端代码调用某一方法(初始化环境)à通过jndi找到ejb组件à找到home接口à通过home接口创建ejb对象àejb对象通过remote接口调用克隆的商务方法àejb对象取得bean实例的返回方法。

2,EJB 3的到来

现在EJB2已经过去了,EJB3到来了。重量级的EJB2过去了,轻量级的EJB3到来了。那么让我们比较一下两者:

1,     EJB3中,一个EJB不再象EJB2中需要两个接口一个Bean实现类

2,     简化后的EJB3sessionBean依靠annotations元注释来定义SessionBean的类型,即使用例如@Stateless表示一个无状态Bean。而且Session Bean中没有了EJB2ejbCreate等多余方法,这样TestSessionBean很象一个普通JavaBeans了。使用Annotation替代了配置文件使得开发更加方便快捷了。

3,     EJB2中,一个EJB对象的调用需要经过两个步骤:JNDI寻找和工厂创建。在EJB3中,为创建型模式的Ioc模式(或称依赖注射)取代了home.create这样简单工厂创建模式。

4,     持久层使用Java Persistence API 替代了EJB2的实体BeanJPAJDO以及HibernateO/R mapping框架都是非常相似的。

 

六,了解一些基本概念:

1,  模式:

模式是实现OO手段之一,目的是为软件松耦合;但是有的模式不是为这个目的,而是为弥补其框架设计问题的,如J2EE核心模式中业务代理模式,如果EJBPOJO的话,就无需在EJB前面再套一个普通JavaBean来解耦客户端和EJB了;

2,  领域建模:

模型代表应用的业务数据和逻辑。Struts框架并没有为设计和创建模型组件提供现成的框架。不过,Struts允许使用其他模型框架来处理应用的业务领域,如EJB(Enterprise JavaBean)JDO(Java Data Object),以及常规的JavaBeanORM(Object-Relation Mapping)

模型是应用中最重要的一部分,它包含了业务实体和业务规则,负责访问和更新持久化数据。应该把所有的模型组件放在系统中的同一个位置,这有利于维护数据的完整性,减少数据冗余,提高可重用性。

根据著名建模专家Eric Evans在其领域驱动设计一书中定义,领域模型划分为实体和值对象两种,实体模型是指业务领域中具有独立属性的对象;而值对象则可能是一种Description或状态或规则。只要有实体对象,就可能存在实体的状态,状态跟踪有时成为一个业务领域使用计算机软件的首要跟踪,但是,数据库不是对象状态的唯一表达方式,只是一种存储方式.

Domain-Driven Design领域驱动设计,DDD开发框架已经层出不穷(如RoRRIFEJdonFramework等), DDD是告诉我们如何做好业务层!并以领域驱动设计思想来选择合适的框架.

我们知道软件的产生过程是:分析、设计、编程、测试、部署。过去,分析领域和软件设计是分裂的,模型驱动设计(Model-Driven Design)抛弃了分裂分析模型与设计的做法,使用单一的模型来满足这两方面的要求。这就是领域模型。   

3,几个易混淆的概念:POVOBODTOPOJODAO:

POpersistent object持久对象基本上就是EntityObject

最形象的理解就是一个PO就是数据库中的一条记录。好处是可以把一条记录作为一个对象处理,可以方便的转为其它对象。

BOBusiness Object,即业务层对象。

主要作用是把业务逻辑封装为一个对象。这个对象可以包括一个或多个其它的对象。
比如一个简历,有教育经历、工作经历、社会关系等等。
我们可以把教育经历对应一个PO,工作经历对应一个PO,社会关系对应一个PO
建立一个对应简历的BO对象处理简历,每个BO包含这些PO
这样处理业务逻辑时,我们就可以针对BO去处理。


VO value object值对象. 早期被作为ValueObjectData Transfer Object的总称。实际上Value Object的真正意义在于它的内容,而不是身份.

VO, View Object,即表现层对象。界面展现需要的对象,如StrutsFormBean

主要对应界面显示的数据对象。对于一个WEB页面,或者SWTSWING的一个界面,用一个VO对象对应整个界面的值。

DTO
Data Transfer Object
数据传输对象
主要用于远程调用等需要大量传输对象的地方。

数据传输对象,在应用程序不同层次之间传书对象,在一个分布式应用程序中,通常可以提高整体的性能
比如我们一张表有100个字段,那么对应的PO就有100个属性。
但是我们界面上只要显示10个字段,
客户端用WEB service来获取数据,没有必要把整个PO对象传递到客户端,
这时我们就可以用只有这10个属性的DTO来传递结果到客户端,这样也不会暴露服务端表结构.到达客户端以后,如果用这个对象来对应界面显示,那此时它的身份就转为VO.

POJO
plain ordinary java object 简单java对象

我们以前常常使用javabeans来携带数据,如果一个JavaBeans对象被Web技术(也就是Jsp/Servlet)调用,那么JavaBeans就运行在J2EEWeb容器中;如果它被EJB调用,它就运行在EJB容器中。JavaBeans组件发展到EJB后,JavaBeans形式就基本消失了,这就自然形成了两种JavaBeans技术:EJBPOJO.

POJO完全不同于EJB概念,指的是普通JavaBeans,而且这个JavaBeans不依附某种框架,或者干脆可以说:这个JavaBeans是你为这个应用程序单独开发创建的。人感觉POJO是最常见最多变的对象,是一个中间对象,也是我们最常打交道的对象。


DAO
data access object
数据访问对象
这个大家最熟悉,和上面几个O区别最大,基本没有互相转化的可能性和必要.
主要用来封装对数据库的访问。通过它可以把POJO持久化为PO,用PO组装出来VODTO
 

 

总结下我认为一个对象究竟是什么O要看具体环境,在不同的层、不同的应用场合,对象的身份也不一样,而且对象身份的转化也是很自然的。就像你对老婆来说就是老公,对父母来说就是子女。设计这些概念的初衷不是为了唬人而是为了更好的理解和处理各种逻辑,让大家能更好的去用面向对象的方式处理问题.

      
大家千万不要陷入过度设计,大可不必为了设计而设计一定要在代码中区分各个对象。一句话技术是为应用服务的。

七,总结:

软件编程之道,恐怕也不是一句两句能说得清楚的。

编程思想与设计思想才是程序的灵魂,

如果你在框架的光辉下迷失了方向,

你就成为了蓝领工人。

 

一个POJO持久化以后就是PO
直接用它传递、传递过程中就是
DTO
直接用来对应表示层就是
VO

相关文章推荐

Java和J2EE的学习之路

  • 2008年05月10日 22:22
  • 14KB
  • 下载

SSH-经典的三大框架 我回来了, 重新学习 J2EE 之路

已经一年多配置过 ssh框架,借空闲时间重新试试这个经典框架,因为我就是从这里开始入门的。本文摘自 博客大神 http://blog.csdn.net/lishuangzhe7047 一个女程序员...

我的J2EE成功之路

  • 2010年02月23日 13:49
  • 514KB
  • 下载

我的J2EE成功之路源代码

  • 2013年12月23日 02:13
  • 20.4MB
  • 下载

在飞实习学J2EE之路:12.9.3 Hibernate的基本流程

实习公司第一天:     刚参加完山东齐鲁软件暑假的大赛,来到公司,第一天没安排工作,自己看了看SSH里的Hibernate。-------2012年的9月3日第一篇(当做日记来写写)    要使...

java J2EE成长之路

  • 2008年08月20日 13:28
  • 1.24MB
  • 下载

转自别处的:J2EE架构师之路

不经意的回首,工作进入第五个年头了,发现走过了从Java程序员到J2EE架构师的历程。 发现电脑上安装了各种各样的J2EE工具:JBuilder, WSAD, Eclipse, Rose, To...

我的j2ee成功之路源码第四章

  • 2012年11月23日 18:03
  • 6KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:J2EE设计师之路
举报原因:
原因补充:

(最多只允许输入30个字)