`
vv_1024
  • 浏览: 110180 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

再论 SSH 应用中 的 PO 与 VO

    博客分类:
  • J2EE
阅读更多
    在目前主流的轻量级框架SSH中,如果符合JPA规范,那就先设计PO模型,再生成数据库。
    PO(persistant object 持久对象)对象模型反映了对象间的关系,如一对多、多对多、单向双向访问关系等。可以看成是与数据库中的表相映射的java对象。

    VO(value object 值对象) 通常用于业务层之间的数据传递,在WEB应用中,一般用于和前台页面做数据相互。

    Struts1.x被2.x代替后VO层消失了,在action中直接传递PO,这样代码显得很简洁,很多SSH应用也都这样做。

    在简单的ssh中,po可以像下面这样:
@SuppressWarnings("serial")
@Entity
public class EmpInfo implements java.io.Serializable {
private Integer id;
private String empNo;
private WorkType workType;
private Set<WorkExperience> workExperiences = new HashSet<WorkExperience>(0);

//下面是get set 方法
}



    但随着系统框架的横向扩展,加入了如webservice、json、报表等功能后,问题也随之而来。

    如果 webservice 使用了 xfire,hibernate一对多关系又是lazy的话,那么必须在PO中对应的set上打上忽略注解,如:
@IgnoreProperty
public Set<WorkExperience> getWorkExperiences() {
	return workExperiences;
}

否则xfire解析容易进入死循环。

    在struts 2.1.6中使用json格式作为输出,也同样面临着上面的问题。PO对象中包含着复杂的关系,如果又是双向的,很容易出错,为了避免错误,我们又要在PO中打上相应的忽略注解,框架一多,各种注解参杂在PO中,显得很乱,最后都搞不清这些注解到底代表哪个功能。

    最后我又重新使用VO,原先PO中存在的一些字段也可以放入到VO中,如:age,PO可完全对应于数据库字段,而把一些需要和前台交互的字段放入VO中,如增加了age(可以根据身份证号计算出),VO中尽量存放简单数据类型,如上面PO中的WorkType(员工工种类型),在VO中就可以直接改成
private String workTypeName;

这样不管是前台使用什么系统(webservice和doNet C#交互,还是使用flex,ajax json等),转换为xml格式也异常简单,制作报表也不用过多的考虑如何解析传递过来的复杂对象和子表嵌套。用户关系的只是workType.name而不是WorkType这个类,VO由业务层产生,传递给视图层或其它各种接口。这样可以使得层次间进一步解耦,PO对象模型也变得容易维护(少了很多注解,代码清晰)。也使得前端数据结构的变得更轻(VO都是简单数据类型),有利于传输和解析。

    以上是我在最近学习中的总结,一般的应用SSH(jsp)action可以直接用hibernate 的 PO,不存在xml解析。


    补充:
    对于复杂对象转换为xml或json格式解析出错的问题,我已经遇到好多次,大家一起说说你们在项目中也遇到过吗?有什么好的解决方案?
2
1
分享到:
评论
1 楼 vv_1024 2009-12-03  
PO 与 VO 的关系是否可以看成类似数据库中的表和视图,以前两层架构的时候大量使用数据库的视图,而现在放到了对象模型中。

相关推荐

Global site tag (gtag.js) - Google Analytics