如果不是在.net下的DataSet(数据源控件)和DataGrid(数据绑定控件)下进行企业开发的话,多半会使用分层的机制进行并行开发。
从O/R Mapping 到IoC Container再到Web Framework.逻辑分层深入人心。
分层,然后对象也细分了,Entity、value object、persistence object, 协作对象,业务对象……
别的不想多说,只说说DTO的历史,以及Web开发中遇到的Open Session in View。
DTO其前身是VO,值对象,其出现环境是作为EJB的补丁模式出现,以求解决多次跨越多个层次的数据传输问题。并且通过粗粒度的数据访问接口减少远程调用的次数,以提高整个基于EJB的分布式应用的性能。
而今,实践证明,逻辑分层并不适合物理分层,(layer != tier )。Web 同 应用的并置往往得到更好的性能。这种系统级的重构,大大削弱了DTO这个模式的存在价值。没有性能的提高,反之,需要编写大量的代码。不少人把DTO纳入了后EJB 时代的反模式之列。
捍卫DTO的人自然也有他们的辩护,VO并不总是等于PO,有时PO比VO小,有时又比VO要大。此外,如果直接把PO放到界面上,会产生两点问题:一、数据存储实际上越过了逻辑层,直接在表现层和持久层之间传递。二、表现层开发依赖于数据库表,并行开发受到影响。
Rod Johson在《J2EE without EJB》中,似乎也是倾向使用PO直接呈现到界面上,我的判断是基于他提到的Open Session in View这样一个界面渲染时解决PO延迟加载的问题。
问题很明显了,如果使用DTO 或者 VO,那么根本不用担心这类延迟加载的问题。代价是必须维护更多的DTO。
但是如果我两者的负担都不想要呢?
最简单的方案就是——不要延迟加载,这很暴力原始,但显然在多数情况下,这样的简单导致的性能乏善可陈是我们不能接受的。
那么还有办法吗?
再回过头去看看DTO 和DAO。
DTO发展自 VO,既而TSS上的人更是精雕细琢,DTO 又产生了若干种类。
《EJB Design Pattern》中列举的就包括:Domain DTO、Custon DTO 、Data Transfer HashMap、DataTransfer Rowset。
而在《Core J2EE Pattern》 中DAO的策略有着类似的分类。
可见,要么是DTO多样话,要么是DAO提供的数据访问接口多样化。
要么是定制几个初始化级别不同的DTO,要么是通过不同的DAO接口返回初始化程度不同的PO(或VO)
似乎天下永远没有免费的午餐。利弊权衡永远的由你自己左右。最近公司的一个产品就打算使用定制更多DAO接口通过 Hibernate.Initialize强制加载实体的更个字段。
这样解决延迟加载,以求绕过Open Session in View和DTO。那么代价呢?
更多的DAO方法。DAO的不可移植?………………
还在权衡中……