﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-大音希声、大象无形-随笔分类-持久层</title><link>http://www.blogjava.net/guitarpoet/category/8704.html</link><description>Java企业级应用软件开发探讨</description><language>zh-cn</language><lastBuildDate>Tue, 27 Feb 2007 15:58:25 GMT</lastBuildDate><pubDate>Tue, 27 Feb 2007 15:58:25 GMT</pubDate><ttl>60</ttl><item><title>Common Persistence概念和构想</title><link>http://www.blogjava.net/guitarpoet/archive/2006/03/22/36816.html</link><dc:creator>guitarpoet</dc:creator><author>guitarpoet</author><pubDate>Wed, 22 Mar 2006 04:19:00 GMT</pubDate><guid>http://www.blogjava.net/guitarpoet/archive/2006/03/22/36816.html</guid><wfw:comment>http://www.blogjava.net/guitarpoet/comments/36816.html</wfw:comment><comments>http://www.blogjava.net/guitarpoet/archive/2006/03/22/36816.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/guitarpoet/comments/commentRss/36816.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/guitarpoet/services/trackbacks/36816.html</trackback:ping><description><![CDATA[除了关系型数据库（企业级应用主要的数据持久工具）之外，企业级应用还需要其他的方式进行持久层操作。比如，数据保存在文件中、数据来自或者流向远程的其
他服务等。这样持久层的操作就会有3——5种之多（还分有事务管理支持的和没有事物管理支持的）。<br /><br />怎么对这么多的操作进行有效的管理，怎么才能使持久层的变更只
限定在持久层的范围内，怎么才能实现业务逻辑开发人员在开发上不必具有很多的持久层框架经验（注1），还有就是怎样实现既可以利用强制和工具辅助的方式使一个新人能够开发出跟掌握持
久层开发的精髓的核心开发人员同样质量的代码（注2）又可以让老手开发起来非常快捷（熟练工种），更重要的是在业务逻
辑方面物质化、代码化积累公司的业界开发经验，这就是我们下面要讨论的问题。<br /><br />
我认为，要想实现持久层的修改（注3）与业务逻辑层分离。还要最大可能的把公用的东西抽象出来，最大可能的为培养业务专精人员提供基础，就必须<span style="font-weight: bold;">要有一个机制，实现把持久层的任务交给持久层去作。<br /><br /></span>这是什么意思呢？<br /><br /><b>就是在系统基础架构上，实现业务逻辑层和持久层的明显松耦合</b>（业务逻辑层根本不必知道持久层到底是什么介质和实现方式）。<br /><br />
但是作为业务逻辑层的对象，数据的持久化操作是它所不能避免的东西，也就是说，它不可避免的会和持久层打交道。<br /><br />那么怎样在代码的级别实现和持久层打交道还不跟持久层相关呢？<br /><br />
这就是要在下面给出的总体设计。在这里简单的介绍一下用到了三个技巧，一个是<a href="http://www.martinfowler.com/articles/injection.html">IOC</a>，一个是<a href="http://www.exciton.cs.rice.edu/JavaResources/DesignPatterns/command.htm">Command模式</a>，还有一个就是CallBack的概念。<a href="http://www.martinfowler.com/articles/injection.html">IOC</a>就是著名的好莱坞模式——你不用来找我，我会自己去找你的，而CallBack通俗一点说就是“你要做什么，你告诉我，到时候我会通知你，并把你想要的东西带来的”。<br /><br />
业务逻辑对象不可避免的要对持久层进行操作，但是它对持久层的操作本身可以抽象成为一个Command对象，由注入到业务逻辑对象中的DAO来负责操作。说通俗点儿就是
说，对业务逻辑对象（BO）而言它是把一个任务说明书（CommandCallBack）给了一个它自己都不知道是从哪里来的叫做DAO的家伙（IOC），然后跟他说：
“你拿着它，按它的指示去把这事儿给办了吧。”；业务逻辑对象知道“这事儿”是什么事儿，因为任务说明书是有名称的，但是至于任务说明书的内容，它就不清
楚了。具体的事情DAO和任务说明书清楚，但是业务逻辑对象只是一个交接。换句话就是说，通过这么一个交接手续，把持久层的东西还给持久层了。业务逻辑对
象只想知道“这事儿”办完的结果，事实上本来就应该这样。<br /><br />
整体设计上面，涉及到了几个持久层开发的基本的技巧，除了IOC、CallBack之外，还有DAO和容器管理。<br /><br />
DAO的模式其实也不是什么新鲜的摇滚Rock'n'Roll了，企业级应用要的就不是新鲜的东西（注4）。这个方式里面用的DAO是通用型的DAO，通
用型的DAO的优点就是接口统一，框架比较容易理解。但是缺点也十分明显，那就是它本身的灵活性是值得怀疑的，JDBC就是一个统一的接口，结果呢，直接
用它就会导致SQL遍布代码，这本身就增加了管理的复杂度，本来就是来封装持久层的，结果跟没封装没有区别，那么这个工作就是值得怀疑的。非通用型的
DAO倒是可以解决这个问题，但是非通用型的DAO就太灵活了，没有办法对它进行良好的封装，而且对于建筑在持久层的基础之上的业务逻辑层架构而言，这种
灵活性导致了只能对业务逻辑操作进行粗放式的封装，可重用的东西相对没有使用通用型DAO的时候多了。还有就是非通用型DAO的开发上面想要实现代码重用
也是比较麻烦的（需要良好的设计）。<br /><br />至于容器管理吗，明天再谈。<br /><br />注1：如果业务开发人员具有很多的持久层框架经验，当持久层框架更
换时，必然会造成他的极度不适应，这通常是系统移植成本很高的原因之一<br />注2 ：这是有可能的，类比一下C++和汇编语言，用Eclipse和用手工进行重构<br />
  注3：包括库表修改、框架更换和方式的修改——事实上，如果业务逻辑发生了修改，那么持久层可能必须得改，但是如果持久层封装的好的话，反之未必亦然<br />注4：公司重要的事情是盈利，根据技术辩证法，任何一个技术有有其优点也有其缺点，都有其适用和不适用的地方，新鲜的技术往往由于是对已有技术的革新，所
以在一段时间内会有很多潜在问题，作为爱好者去试用去跟技术的负责人联系当然是没问题，但是作为企业，对产品是质量要负有法律责任的，一般的公司当然都不
会愿意当新技术的小白鼠。相对而言，旧的技术由于拥有广泛的使用，优点和缺点广为人知，熟练开发人员也比较容易找到，可以在开发中规避其自身的缺点。当
然，不新鲜的也得看着要，得根据实际情况再作决定。<br /><img src ="http://www.blogjava.net/guitarpoet/aggbug/36816.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/guitarpoet/" target="_blank">guitarpoet</a> 2006-03-22 12:19 <a href="http://www.blogjava.net/guitarpoet/archive/2006/03/22/36816.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JavaEE持久层开发方式现状和简单评价</title><link>http://www.blogjava.net/guitarpoet/archive/2006/03/21/36569.html</link><dc:creator>guitarpoet</dc:creator><author>guitarpoet</author><pubDate>Tue, 21 Mar 2006 02:29:00 GMT</pubDate><guid>http://www.blogjava.net/guitarpoet/archive/2006/03/21/36569.html</guid><wfw:comment>http://www.blogjava.net/guitarpoet/comments/36569.html</wfw:comment><comments>http://www.blogjava.net/guitarpoet/archive/2006/03/21/36569.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/guitarpoet/comments/commentRss/36569.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/guitarpoet/services/trackbacks/36569.html</trackback:ping><description><![CDATA[
基于JavaEE的分布式三层企业级应用的数据存取方式有很多种，比如关系型数据库、普通文件、远程服务等。但是数据的存取主要采用关系型数据库，下面主要关注关系型数据库的持久层开发方式。<br /><br />
开发方式大体以下几种方式（括号内为目前使用它的工作难度、强度，记住，我们讨论的是动辄就上百个表、几个业务小组联合开发的企业级应用，所以工作强度的估计一点儿也没有夸张）：<br /><ol><li>
    直接JDBC操作（简单，小）：底层操作（注1）较多，弄不好就会造成业务逻辑层和持久层的高度耦合。
  </li><li>
    SQLMapping（比较简单，一般）：把底层操作全部提取出来统一进行管理，本身并没有对概念上进行什么革新。但是这种统一的处理在逻辑上其实属于分而治之的逻辑，通过良好的对它的使用可以体现出松耦合实现持久层的要求，也相对比较便于管理和修改。<br /></li><li>
O/RMapping（有学习曲线，没有工具支持会相当大）：存在的时间已经很长，我认为它的最主要的作用是关系型数据库的反设计——关系型数据库的设计
就是要把现实中的对象和对象间关系设计成实体和实体间的关系映射。而O/RMapping恰好相反，它是把实体和实体间的关系映射还原回对象和对象间的关
系。<br /></li><li>
Entity
EJB（有学习曲线，没有工具支持会相当大）：我没有对它进行过深入的研究，但是从J2EE的概念上看，它是属于O/RMapping概念的一种。它既是
一个事实上的工业标准而且又体现了EJB的容器管理特性。本身其实是很值得研究的，但是由于目前而言EJB3.0刚刚起步，而EJB2.0的开发也确实比
较麻烦，还有等等等等一系列的其他事情，我对它暂时处于观望态度。 </li><li>
DataSet（比较简单，看实现方式）：这是所有从PB和C++Builder年代走过来的人最喜欢的方式，它并没有对关系操作进行对象封装，但是它却
在对象级别对数据库的操作进行了比较好的封装，相对而言它的使用难度跟SQLMapping
相当，但是工作强度却比SQLMapping要低。目前IBM和BEA提出那个CommonJ的持久层操作Service Data
Objects没用过，不提什么意见，但是MS.NET的ADO.NET倒是用它做过项目，有点了解。MS的ADO.NET主要是通过DataSet经由
DataAdapter进行数据持久化操作，由DataSet记录每一次对它的数据操作，在重新得到数据库连接后，会经由DataAdaptor通过分析
元信息（一般也是映射）和数据操作记录来自动生成该执行的SQL语句。DataSet本身可以跟XMLSchema等同（两者可以相互转化），所以在表现
XML数据的方面它是当仁不让的。我认为DataSet的机制是ADO.NET的核心机制，也是微软在应用开发方面策略的所在。</li></ol><br /><span style="font-weight: bold;">评价：</span><br /><br />不用说也能清楚，直接JDBC操作的方式持久层和业务逻辑层耦合最严重，只要持久层有一点改变，业务逻辑层就得相应的改变重新打包和部署，反之亦
然。事实上一个超过300个Class文件和500个JSP的中等项目中遍布JDBC直接操作的话，数据库库表和业务逻辑的每一处小的修改都是一场噩梦。
<br /><br />SQLMapping还算可以接受，事实证明SQLMapping是替换掉JDBC的最好方式，如果你现在还在执意于使用直接使用JDBC的话，换
SQLMapping好了，效率不低，开发起来跟直接直接使用JDBC差距不大，<a href="http://ibatis.apache.org/" title="iBatis">iBatis</a>就不错。<br /><br />
O/RMapping是一个重头戏，它是目前唯一的一种用面向对象的方式解决关系型数据库持久化问题的方法（我觉得也是目标明确的方法）。有趣的是，关系
型模型的范围要比对象化模型宽泛，这样就造成了，过去的系统设计中对对象化模型考虑的不够，使得过去系统的中的数据存储方式对O/RMapping实现不
利（这是事实）；还有就是很多数据为中心的业务处理（比如计算电费，报表数据处理），用对象化模型不太合适（注2），这种情况下，O/RMapping实
在是不能长袖善舞。<br /><br />
DataSet是一种万金油式的对象化解决方案，处理小型的项目绰绰有余，处理大型的项目就有点力不从心了。万金油式的解决方案最大的缺点就是高不成、低不就，虽然在使用上它是相对简单的。我倒没有说ADO.NET本身有问题，其实.NET也有O/RMapping啊。<br /><br />综上所述，我们可以得出结论。目前而言所有流行的持久层实现方式都有其优点和缺点（技术辩证法）。作为商业化的企业级应用而言，一个技术坚持到底的
路是走不通的（肯定会在技术的缺点上吃大苦头）。我推荐至少要使用两种以上的技术进行持久层封装（我推荐O/RMapping +
SQLMapping +
JDBC——实在是解决不了的问题再找JDBC），要采用务实的方式进行技术选择，而不要迷信哪一种技术，对于大型企业级开发而言，目前没有银弹。<br /><br />
注1：按我的话说是Dirty Work<br />
注2：本身可重用性就不够（各处的算法都有不同），但是对运行时效率的要求却很高（有的时候甚至Java本身的效率都不足以达到要求，只能求之于其他语言）<br /><img src ="http://www.blogjava.net/guitarpoet/aggbug/36569.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/guitarpoet/" target="_blank">guitarpoet</a> 2006-03-21 10:29 <a href="http://www.blogjava.net/guitarpoet/archive/2006/03/21/36569.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>