VO(DTO)模式在分层架构设计中是否需要的扯淡
Peter Wei
引子: 前两天,在内部讨论中。公司有一开发人员向我抛出问题:我们Web层和App应用层用DTO(VO)对象,没有直接用PO,你有什么好的建议?我自然知道他说这句话的意思,PO到DTO(VO)的不停转换,太麻烦,增加太多工作量了。因为我是负责系统架构的,他是想让我向上面CTO反映取消掉DTO对象。但现有的架构是原先就有的,而且在一定程度上,我也认为需要用DTO对象。所以最终没有全部取消。
概念扫盲 我们现在大多数的应用,我想都是基于分层架构的:
Web层(Struts2
or SpringMVC等)App应用层(Service)Dao层(ORM)DB PO:也就是一般概念上的Domain Object,如hibernate
中的Entity.一般用于Service层--Dao层间的数据传输。
DTO(VO):也就是一般意义上的VO,封装后的对象。一般用于Web层—Service层间的数据传输入。 VO(DTO) VS PO 引子中开发人员是想用PO透传所有层。也就是共用PO,然后取消掉DTO。
1.PO透传的代码示例: 比如有一个Order的hibernate entity.
我们假设Order下还有Account等好几个对象和集合。
- public class OrderAction{
- private Order order=new Order();
- private List<Order> orderList
- public String add(){
- orderService.add(order);
- return xx;
- }
-
- public String query(){
- orderList=orderService.find(Object param);
- return xx;
- }
- }
-
- public class OrderService{
-
- public void add(Order){
- orderDao.saveOrUpdate(Order o);
- }
- public List find(Object param){
- return orderDao.find(Object param);
- }
- }
2.用VO(DTO)模式的代码示例:
- public class OrderService{
-
- public void add(OrderVO vo){
- Order order=new Order();
- Account account=new Account();
-
- account.setXX(vo.getXX);
-
- order.setAccount(account);
-
- orderDao.saveOrUpdate(Order);
- }
- public List<OrderVO> find(Object param){
- List list=orderDao.find(Object param){
- for(xxxx){
-
-
- setXX
- setXX
- }
- }
- }
- }
PO的透传的优点一目了然,就是不用进行大量的数据对象转换,极大的减少开发人员的工作量。而且大多数PO和VO是重合的,属性什么都一样。我们知道虽然有BeanUtils等工具进行自动转换,但依然很繁琐。
- BeanUtils.copyProperties(desc,src);
为什么用VO(DTO) 我在以前的工作过程中做过各种企业应用还有网站应用。大多数的项目,我们都用的是PO透传View,Action,Service,Dao层。但有两个项目中没用。
1.一个是联通的某OSS系统,该系统的基本技术架构是这样的: Flex(Web层)BladeDSBusiness
Facade(DTO)Service(Spring)Dao(hibernate) 我们一眼看出这是一个分布式的系统。也就是Flex和Java应用通迅的异构系统。在Flex和Java应用之间用DTO模式结合外观Facde模式就顺理成章,水道渠成了。为什么呢?因为两个进程间的通迅,复杂层级的Hibernate
Domain
Object不好直接传到Flex端,因为是用remote协议传输。Hibernate的lazy特性以及序列化都是个问题。所以加一个外观层进行PO到DTO的传输就很有必要了。
2.一个是一个电子商务网站,网站的基本技术架构是这样的: 有两部分,一部分是内部管理核心系统:
Flex应用Hessian
Remote协议App Service(Sring)Dao(hibernate) 另一部分是电子商务系统,也就是对外的部分
Web应用(Jstl,jsp,SpringMVC)Hessian Remote协议 App
Service(Sring)Dao(hibernate) 其中Flex应用单独部署一个工程,Web应用单独部署一个工程,App
Service和Dao又部署一个工程。Flex和web应用都是单独通过hessian协议访问App应用。
我们来总结一下为什么要用DTO:
1.
JavaEE各层之间解耦,这是从设计角度来说的。也就是说Domain
Object(PO)直接封死在Dao层。高内聚,低耦合是我们追求的一个目标。但由于在一般的应用中大量的PO,VO转换,增加了工作量,也有些人说是过度设计。
2.
隔离变化。当在一些大型的应用场景以及Domain经常变化的系统里,View层可以只关注DTO对象,不用关心Domain层PO对象,如hibernate
entity的不断变化。
3.
利于发挥个人技术特长,特别是按层来分工开发的团队。如有人专注于Web层,只做SpringMVC和界面这部分。还有人专门做Spring和Hibernate部分。两组的开发人员定义好接口数据就行,也就是DTO(VO)。我们当时做的电子商务网站就是这样的。
4.
当系统发展大后,扩展成各种前端界面后,可以有效隔离核心应用层。如又有web界面,又有swing的cs界面,又有手机客户端。
5.
当分层部署时,也就是Web层(jsp,Struts2)和App层(Spring,dao)在不同机器上时,用Remote协议通迅,DTO是必需的。如处理hibernate
lazy load和序列化等问题。在电子商务应用中分层部署的主要好处是减少各层负载量,提高性能。
6.
在一些特定场景,如需要防火墙的地方,需要把核心数据层(Service,Dao,DB)放在防火墙内。
小结 综合以上所述,
我认为VO(DTO)模式还是必需的,特别是考虑到以后扩展性的问题。但是在我们的团队中为了开发进度和避免对以前开发的功能影响,没有强制要求在Action和Service层间一定用DTO.但是新开发的功能模块要求用DTO模式,算是一种折中吧。以后系统大了之后再重构好了。要不然以后怎么有事做呢?哈哈。而且boss有时间压力在那。毕竟现在还没打算分层部署,够用就行,先不过度设计了。
其它牛人的一些观点:
参考:
Martin
Fowler的POEAA(企业应用架构模式)中分布式模式中的Remote Facade模式和DTO模式。
Rod
Johnson在J2EE without ejb中是反对用DTO的。
欢迎拍砖,谢绝漫骂!
相关推荐
个人对DTO这种设计模式的一些粗略见解。
原代码生成组件,默认会在最终生成文件名前,默认附加实体名前缀,例如实体名是User,VO.java.ftl会自动生成UserVO.java,这样没问题。但是对于前端页面,如list.vue,edit.vue,因为是分目录放实体,希望最终文件名...
Java中 PO VO BO DTO DAO 和 POJO 关系图
java简单基础 需要的了解一下 我们大家还是有必要去区分的
NULL 博文链接:https://eddysoft.iteye.com/blog/1941484
J2EE基础知识之DTO,VO,PO,DO等定义J2EE基础知识之DTO,VO,PO,DO等定义J2EE基础知识之DTO,VO,PO,DO等定义
DTO设计模式已被广泛用于JavaEE项目中,尤其是在那些使用EJB,SOAP,REST等技术的项目中。讨厌编写DTO类并将这些值转换为Bean并反之亦然的开发人员。使用此API有一些简单的步骤,并将提到一些重要的注释。您所需要的...
NULL 博文链接:https://ewf-momo.iteye.com/blog/1738853
PO可以严格对应数据库表,一张表对映一个PO。... VO:value object值对象、view object视图对象 PO:持久对象 QO:查询对象 DAO:数据访问对象——同时还有DAO模式 DTO:数据传输对象——同时还有DTO模式
J2EE开发人员必须知道 Java Web开发中VO、PO、DTO、POJO代表含义。
FreeMarker通用模板。... 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。 模板编写为FreeMarker ...在模板中,你可以专注于如何展现数据, 而在模板之外可以专注于要展示什么数据
JAVA 中 的 什 么 是 POJO、VO、PO、DO、DTO 都 是 什 么 ? 他 们 有 什 么 区 别 ?
把分页按钮写在dto里,其他dto继承他
本人以前搞不懂这些o的区别,特意查找资料总结了一下,希望也可以帮到其他人
简单的EntityFramework4.3+三层+DTO,如果需要简化版的,我的资源里有一个不含DTO的版本。 这个Demo的主要功能是: 1、实体类的创建、复杂类型的嵌套 2、实体类的配置(主键、...需要的DLL文件都在packages文件夹中
时钟分频在数字信号处理中是非常普遍的使用,针对非1/2的分频,这里我们介绍一种离散时间振荡器设计(DTO),可以基于主时钟clock下实现任意分频。这种方法在需要运用载波传输信号的时候通常使用此方法。
java DTO 详解 java DTO 详解 java DTO 详解 java DTO 详解
登陆的dto.zip