<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>零雨其蒙</title>
    <description></description>
    <link>http://sslaowan.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>一条凭空消失的短信引发的思考</title>
        <author>sslaowan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sslaowan.javaeye.com">sslaowan</a>&nbsp;
          链接：<a href="http://sslaowan.javaeye.com/blog/196899" style="color:red;">http://sslaowan.javaeye.com/blog/196899</a>&nbsp;
          发表时间: 2008年05月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <em>一条凭空消失的短信，引发了一个信管人深深的思考，究竟是什么原因，造成了奇怪的现象。因为发生在午夜十二点多，某种神奇的力量删除了短信，还是手机系统的一个Bug。那为什么使用了整整一年第一次发生这样的事情，究竟是偶然还是必然？请收看，即将为您播出的大型记录片——《秘境追踪III》之《一条凭空消失的短信》</em><br /><br />   2008年5月26日零点，星像往常一样，跟璇儿打完电话，然后又给她发了条短信，不久之后，璇儿回复了短信：“星，请你相信，我是你一个人的。”星收到查看后，迅速回复了短信，回复完后，返回短信列表，让星想不到的事情发生了——刚刚收到的那条短信，竟然凭空消失了……<br /><br />   在上世纪90年度末期，新的有关鬼与神的传说发展到了手机，电脑网络等新生事物上，一系列有关鬼通过互联网和手机网络与人对话，甚至控制人类的故事开始流传。而这个时间，一般恰好都是零点！<br /><br />   星作为一个思维严整的信管人，首先考虑到的是，可能是误删除了短信。以前发生过这样的事情，收到短信后，由于手忙脚乱，一不小心删除了刚刚收到的短信，以前这也引起过星的不满，因为删除时，系统不会提示删除确认信息，这是违反友好性原则的。可是，当星收到这条短信的时候，很从容的查看短信并回复，不会存在误删的情况。<br /><br />   接下来，星推测这极有可能是手机偶然出现的Bug。是不是短信收到后，系统出现故障，自动将短信删除了呢？星带着这样的疑问，和收到短信的幸福，关掉手机睡去了。<br /><br /> <br /><br />  <em> 一条凭空消失的短信，引发了一个信管人深深的思考，究竟是什么原因，造成了奇怪的现象。因为发生在午夜十二点多，某种神奇的力量删除了短信，还是手机系统的一个Bug。那为什么使用了整整一年第一次发生这样的事情，究竟是偶然还是必然？请收看，正在为您播出的大型记录片——《秘境追踪III》之《一条凭空消失的短信》</em> <br /><br /> <br /><br />   2008年5月26日早上7点40分，星打开手机，再次收到璇儿在零点二十几分发来的短信，随之又收到了几个朋友的短信，星回复了其中的一条，然后准备看完其他短信返回短信列表再逐一回复，结果奇怪的现象再次发生，所有刚刚收到的短信都不见了！<br /><br />   星又转到发件箱，发现刚刚发出的短信，以及零点回复璇儿的短信也都不见了。星意识到，这不是一个系统Bug，也不是一个偶然事件。因为，这个手机已经使用了一年零三个月，收发短信数万条，那么26号零点出现了一次错误，那就是说概率是数万分之一。而在26号早上，5条短信都消失了，也就是小概率事件频繁发生，这几乎是不可能的！<br /><br />   那么会不会手机设置问题呢？之前，星的母亲突然收不到星的短信，接连几天都是这样，最终查明原因，竟然是在不知不觉地情况下，将星加入了短信黑名单，收不到短信就不足为怪了。星马上开始在手机中查找有关设置，发现对于发送短信而言，确实存在一个“是否保存发送短信”的选项，而这个选项的当前状态是：保存。而对于收件箱而言，并不存在这样一个设置。因此，设置问题也被排除了。那究竟还会有什么原因，会造成如此诡异的现象呢？<br /><br /> <br /><br />   <em>一条凭空消失的短信，引发了一个信管人深深的思考，究竟是什么原因，造成了奇怪的现象。因为发生在午夜十二点多，某种神奇的力量删除了短信，还是手机系统的一个Bug。那为什么使用了整整一年第一次发生这样的事情，究竟是偶然还是必然？请收看，正在为您播出的大型记录片——《秘境追踪III》之《一条凭空消失的短信》</em><br /> <br /><br />   当星陷入沉思之时，同屋的室友，软件工程专业的王超提示说，有可能是内存已满，接收不到短信。确实很多人的手机会存在这样的情况，但是这同样引起怀疑，一是因为星可以收到短信，只是没有保存下来，有可能是因为没有空间保存，所以只是暂存一下系统马上就删除了？二是因为星的手机可以至少储存1千多条短信，而现在只保存了200多条，数据相差甚远。这时王超又提示，这有可能是因为短信和其他诸如照片、音乐之类的文件共享手机内存，那些文件占据了大量空间，导致了短信无处存储。星发现这是个有意义的提示，便去核查手机内存，系统显示：<br /><br />  我的文件 60.7%已用   我的数据22.4% 已用  SIM卡内存 76.9已用   内存卡 29%已用<br /><br />  可以看出，剩余空间对于每条只有几Kb的短信而言，还是相当充裕的，因此，内存卡不足的假设，也被排除了。<br /><br />  这时，星又收到一条短信，他发现收件箱里统计的短信总数，比之前多了一条；星观察了发件箱的短信总数，然后回复了这条短信，发件箱的短信总数也增加了一条。这也引起了星的怀疑，出于职业的敏感，星想到，发送或接收短信时，系统要做三件事，一是接收或发送短信；二、将其保存到本地以供用户查看；三是更新短信总数。设计师们通常会将这三件事情纳入一个事务处理之中，这样首先就要满足ACID中的原子性，即一个事务中的所有事情，要么全发生，要么就全不发生，即全失败。如果据此推论，既然系统已经更新了短信总数，那么也应该同时完成短信存储！那么如果设计师不将其纳入同一个事务之中呢？星觉得这样的可能性同样很小，因为如果存在如此的严重的事务配置缺陷，数万次的短信收发，也应该早就会出现这样的问题了。<br /><br />    那么，据此推论，短信应该是存储在了手机上，那为什么返回列表时，却没有发现呢？难道手机之中还存在什么惊人的秘密吗？<br /><br /> <br /><br />   <em> 一条凭空消失的短信，引发了一个信管人深深的思考，究竟是什么原因，造成了奇怪的现象。因为发生在午夜十二点多，某种神奇的力量删除了短信，还是手机系统的一个Bug。那为什么使用了整整一年第一次发生这样的事情，究竟是偶然还是必然？请收看，正在为您播出的大型记录片——《秘境追踪III》之《一条凭空消失的短信》</em><br /><br /> <br /><br />    星的手机收件箱中有200多条短信，发件箱中也有100多条短信，而每屏只能显示3条短信，因此，星之前并没有逐一审查一遍已经接收的短信。由于发件箱的短信数量相对而言较少，因此星开始逐一查看发件箱的短信，2008年5月25号，共计发出短信57条，而5月26号竟然没有短信！<br /><br />    看了一遍没有发现异常，星又仔细看了每条短信的摘要，忽然找到了刚刚发出的短信！这证明了短信并没有丢失。然后星又随即转入收件箱，5月25号收到短信42条。星仔细查看，很快找到了那些原以为已经消失的短信。<br /><br />    星马上被接收短信的日期吸引了，为什么明明是26号收发的短信，显示的日期是25号呢？忽然，星想起了，26号零点，星刚给璇儿打完电话，回到屋里看到电视上正好出现整点时间，星看了一下自己的手机，显示的时间还是11点58分，于是就很快的修改了手机时间，将时间改为0：00。但是，星忘记了修改日期，也就是手机的时间被改成了2008年5月25日0点0分！又由于手机接到短信后，按照手机时间保存短信，手机的短信列表也是按照手机时间对短信进行排序，因此2008年5月26号接到的短信，实际上被保存成5月25号收到的短信，然后与真正在25号收到的短信混排在了一起。而这些短信由于是按照25日0点多收到的短信，因此排在了真正25号收到的短信的前面，也就是向下移动了40多条短信，每屏只能容纳3条，也就是要按20多下向下方向键才能看到实际上是26号早上收到的短信，而最初发现短信消失时，星并没有向下滚动过这么多条！<br /><br />    星又仔细对比了真正在25号收到的短信和在26号收到但是被保存为25号收到的短信，在短信阅读状态（而非短线列表状态）下，25号收到的短信显示的时间是7：34 05/25/2008，而26号收到的短信会显示7：45，即当天收到的短信不会显示日期。<br /><br />    Moto E2按照手机时间保存短信，查看短信时，则会看到真正的短信“发送时间”，这个时间应该是获得的服务器或者交换机时间。<br /><br />    如果星的手机不是存在那么多条短信，并且是单天就存在50余条短信，应该很快就能发现这个题，但是由于数据量很大，导致了排错的困难。那么，这样一件事情，能带给我们怎样的启示呢？<br /><br /> <br /><br />    <em>一条凭空消失的短信，引发了一个信管人深深的思考，究竟是什么原因，造成了奇怪的现象。因为发生在午夜十二点多，某种神奇的力量删除了短信，还是手机系统的一个Bug。那为什么使用了整整一年第一次发生这样的事情，究竟是偶然还是必然？请收看，正在为您播出的大型记录片——《秘境追踪III》之《一条凭空消失的短信》</em> <br /><br />    星随即总结了这件事对于信息系统开发而言带来的三点重要的启示：<br /><br />    1 当保存重要信息时，应该获得系统时间，而非本地时间，尤其是目前星正在负责研发的财务结算系统，即使是一般的系统，也会由于各个终端的时间不同，而导致共享数据排序的混乱。<br /><br />    2 当出现数据丢失，幻读等奇怪现象时，应该考虑是不是事务处理出现问题。<br /><br />    3 在构建企业信息系统时，由于数据量都比较大，当出现一些莫名其妙的问题时，应该去查看这些数据去辨别错误原因。同时，采用测试驱动开发，也要多试验一些典型数据，当在运行过程中出现由于某些数据引起的异常，应该单独编写测试用例，以编写新的方法来满足需求。<br /><br />    另外，修改手机时间时，特别是跨天修改时，一定要记得修改日期。<br /><br />    星同时对系统的用户友好性的一系列问题展开了思考，也许生活中的每个瞬间都会给你一些启示，每个人生的过程都是一种体验和提高的机会，与其抱怨一些事情，不如认真地去对待，并期望能从中学到什么，以这样的一种心态去面对原本不喜欢的事情，就会获得一种救赎了。
          <br/>
          <span style="color:red;">
            <a href="http://sslaowan.javaeye.com/blog/196899#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 26 May 2008 10:26:48 +0800</pubDate>
        <link>http://sslaowan.javaeye.com/blog/196899</link>
        <guid>http://sslaowan.javaeye.com/blog/196899</guid>
      </item>
      <item>
        <title>关于企业应用和Web的一些看法</title>
        <author>sslaowan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sslaowan.javaeye.com">sslaowan</a>&nbsp;
          链接：<a href="http://sslaowan.javaeye.com/blog/190639" style="color:red;">http://sslaowan.javaeye.com/blog/190639</a>&nbsp;
          发表时间: 2008年05月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          1 从我的研究来看，企业应用中无非就是业务对象（数据），业务流程，业务规则，业务操作（服务）这些东西，不同的方法论，以及不同实践经验的专家对于这些内容的倾向性不同。在Ajax and REST那本书里，将ROA和以数据库为中心视为同属于以数据为中心阵营，将Web Server看成一个巨大的数据库，然后HTTP协议提供标准CRUD操作接口。而从Fielding论文出发，我更以为ROA与OO是一个阵营的。在IBM的BPM体系中，把业务对象这些东西都定义为Resource，我觉得也是这个道理。资源是抽象程度更高的对象，业务对象（对象中的实体）可以成为划分资源颗粒度的依据。而HTTP操作，应该就相当于实体对象持久化。我想这是REST与企业应用结合的一个点。<br /><br />2 关于流程密集型，我觉得所谓Workflow或BPM引擎，是SRP，关注点分离，和软件复用等软件工程思想的结晶。这样考虑，流程与服务，资源等概念是一个闭环系统。我觉得IBM的BPM在Big Web Service方面的架构，已经将其融和起来了。我写了篇论文是讲如何借助REST将RESTful Web Service与BPM融和起来。<br /><br />3 关于Web与企业应用，我觉得这也代表了两种不同实践经验的专家看问题的出发点。Web的出现是为了信息共享，后来延伸到企业应用，这个阵营的人看问题，是以Web作为前端，Application作为后端，所以他们看到的是一个大大的Web，和一个小小的Application，因此当Application变得超出了他们想象的大后，就认为其复杂程度超过了其本身；而企业应用专家，是以Application为前端，Web为后端，从Application--->Web的方向看问题，Web只是一种表现层，所以是一个小小的Web，一个大大的Application。而企业应用专家又分为两大阵营，像J2EE，.Net这个圈子里的人认为应使用高级语言来搞定业务，数据库只是持久化的一种手段，可以用flat file，LDAP，Stream等其他手段替代。而数据库阵营则认为企业应用的核心是数据库，这就又回到我说的第1个问题上去了。<br /><br />     在做项目时，总是在和持不同观点的人争论一些问题，我思考很长时间，为啥大家会有这么大的分歧，以上是我的一些体会。
          <br/>
          <span style="color:red;">
            <a href="http://sslaowan.javaeye.com/blog/190639#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 07 May 2008 16:26:20 +0800</pubDate>
        <link>http://sslaowan.javaeye.com/blog/190639</link>
        <guid>http://sslaowan.javaeye.com/blog/190639</guid>
      </item>
      <item>
        <title>什么算精通？</title>
        <author>sslaowan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sslaowan.javaeye.com">sslaowan</a>&nbsp;
          链接：<a href="http://sslaowan.javaeye.com/blog/184880" style="color:red;">http://sslaowan.javaeye.com/blog/184880</a>&nbsp;
          发表时间: 2008年04月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          什么能算上精通啊？（讨论的目的在于正确定义“精通”）<br />     比如Hibernate，你对Hibernate的源码了如指掌，知道Hibernate做到的每件事背后的实现代码，可是你不懂为什么要使用Hibernate，ORM的理论，数据库理论（关系数据库，各种实体关联，数据库特性），那能算精通吗？<br />     你懂得了所有的ORM的原理，每一种映射的动机都被了解，如果你不知道在何种情况下、如何使用Hibernate功能，做出好的决策，将其发挥的恰到好处（实战中的Hibernate，与各种数据库特性，记得Rod Johnson在将直接使用JDBC的缺点时，有分析了各种主流关系数据库的错误码问题），那能算精通吗？<br />     你在某个项目中恰当的运用了Hibernate，但是你没有在各种行业、各种类型的项目中恰当的使用Hibernate，那能算精通吗？<br /><br />     如果按此标准，有谁敢说自己精通？<br />     精通C语言，精通数据结构，从原理到实战，从明白为什么到熟练怎么用，到能够正确地在每种场景下使用，如果公司确认是要招聘一个精通XX的人，这个人要么是空集，要么肯定身价千万，而且可以数的过来。<br /><br />     在自己开发的领域能够熟练使用，或者在新的领域能够快速的熟练使用，我觉得已经是很不错了吧~~<br />    <br />    忽然看到一个人的简历，写着语言：英语：一般；中文:熟练；粤语：精通。<br />   <br />     这位仁兄莫非能讲出来每个粤语词的来龙去脉（Hibernate源代码）？我想不能，那么他可能就是广东人，如果他说自己精通（知道在何种场合如何恰当的使用），你会反对吗？我想不会。
          <br/>
          <span style="color:red;">
            <a href="http://sslaowan.javaeye.com/blog/184880#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 21 Apr 2008 13:08:23 +0800</pubDate>
        <link>http://sslaowan.javaeye.com/blog/184880</link>
        <guid>http://sslaowan.javaeye.com/blog/184880</guid>
      </item>
      <item>
        <title>企业级应用，有什么理由不用OO？</title>
        <author>sslaowan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sslaowan.javaeye.com">sslaowan</a>&nbsp;
          链接：<a href="http://sslaowan.javaeye.com/blog/181045" style="color:red;">http://sslaowan.javaeye.com/blog/181045</a>&nbsp;
          发表时间: 2008年04月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这里所谓的企业级应用，就是Martin Fowler的<em>企业应用架构模式</em>中论述的企业级应用。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在软件工程过去的40年里，虽然没有任何一种方法论能够达到舍我其谁的程度，但是确实在工业界和学术界达成了一些共识：封装，行为优先于数据考虑，依赖于抽象而非具体，迭代开发，领域驱动设计&hellip;&hellip;而OO范型是这些最佳实践的最好集合。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 软件的设计，来自对于问题域的抽象，随着对于需求的理解深入，我们的设计会随之演化。结构化范型中首先设计数据库，我认为过早的对问题域进行了数学抽象，往往那些抽象过于远离问题域，它代表了当时对于问题域的理解。而数据库又属于依赖的最低层，这种不牢靠的抽象必然会造成设计的不稳定，因此从本质上讲，这种方法就是不可靠的。而OO可以直接去模拟业务领域，可以尽可能的去贴近实际。因为实际业务运行良好，那么你所设计的模型也会更容易的运行良好。我发现越是贴近现实领域的建模，其进化性越好。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 问题领域中不仅包含实体，还包含值对象，服务[Evans03]，而数据库建模则往往只强调实体。那么其他有用领域概念就在设计中丢失了。制作大而全的对象是不切实际的，对象属性和行为的确定要来自于业务需求，对象使得添加和减少属性和行为都变得容易。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 把一些行为和数据按照主题加以分类，写到不同文件里，就像我们写文章需要划分段落一样，每个段落表达一个意思，如果想补充表达某个意思，就去相应的段落扩展。而类就是这一个个段落。当某个段落表达了不同的意思，就按不同的意思分解。我想这和单一职责原则是有同构性的。那一个个函数就像一个个句子，面向过程设计将这些句子按照应用分布在应用中，而面向对象设计奖这些句子按主题分布在具有业务语义的类中。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 企业级应用的特点是：复杂和多变。一个复杂的东西在变是最让人痛苦的。于是尽可能要把它分解为小而简单的东西，让每个变化只局限于一个方面。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 某些东西是不容易变化的，比如商业，申请服务，提供/享受服务，结帐，这个大方向是不会变的。商业的一个子集，餐馆，上千年了，基本流程还不是点菜，上菜，买单？菜和帐是千年不变的实体。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 无疑，OO比数据库建模向前又走了一步。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 做了几个大型系统，和一些需求模糊、变化无常的项目，真找不出什么理由，做企业级应用可以不用OO。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<strong><span style="color: #008000;"> 2008年4月10号补充：</span><span style="font-size: small; color: #ff0000;">但是，现实情况却是</span></strong>，很少有项目采用OO范型，人们认为无论什么方法都不可能彻底解决企业应用核心复杂性（即问题域复杂），转而走向干脆不尝试OO。特别是在这个行业混迹多年、并且在学校只学了结构化方法的人。我与几个公司的信息部的人聊天，他们采用的方法都是先设计数据库，然而我用OO为系统添加了一项功能（我们为他们公司开发了系统，然后我去添加新功能），他们对于使用OO表示赞同，觉得是好方法。但是却没有使用。</p>
<p>&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="color: #008000;"><strong>2008年4月13号补充</strong></span>：需求调研一个阶段告一段落，回到北京准备考试。在火车上一直跟同学讲领域驱动开发，讲我过去做的两个使用OO开发的项目的感受，并对比之前使用面向过程方法做项目的感觉：</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 领域驱动设计，越是复杂、变化灵活的项目越要采用贴近领域的对象模型，只有小的项目才可以尽可能简化对象使得测试刚好通过即可。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 切忌UI驱动设计。我做的视频监控项目从最初的需求里包含GUI，到后来不要UI，真是惊天动地的大变化。另外一个作业管理的界面我们修改了20多版，而业务还是那点儿业务。UI可以辅助挖掘需求，但是把它作为最后一件事完全可以。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3 切忌数据库驱动设计。关系数据库以数学为基础，距离现实领域太远，过早陷入其中危害无穷。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;面向对象是比面向数据、面向过程更加先进的方法。我说，当做那个作业管理子系统时，我将函数拆分的非常细，每个函数都是单一职责的，但是管理起来很费劲。我举例说，比如你有一堆帮助文档，包含了J2EE的方方面面，为了方便查找，我想你可能会按照主题将他们放在不同的文件里，然后再放到不同的文件夹里。那么这些文件就是类，文件夹就是包。虽然面向过程编程，你可以采用良好的命名规范，并将其放入单独的文件里（比如Delphi的unit，VB的module），但是其封装性和复用性明显要弱于OO。也就是这种最佳实践再向前迈一步就是OO了。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5 我的感觉是，越是大型、复杂的商业应用越适合采用OO。虽然OO不完美，OO不是银弹，OO也没有REST、SSOA等时髦，也许话题很陈旧，很&ldquo;入门&rdquo;，但是，OO在国内应用的现状，就足以反映出，这是个值得探讨的问题。</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>[Evans03]Eric Evans，2003，领域驱动设计：软件核心复杂性解决之道。</p>
          <br/>
          <span style="color:red;">
            <a href="http://sslaowan.javaeye.com/blog/181045#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 09 Apr 2008 22:43:22 +0800</pubDate>
        <link>http://sslaowan.javaeye.com/blog/181045</link>
        <guid>http://sslaowan.javaeye.com/blog/181045</guid>
      </item>
      <item>
        <title>广州出差生活日记（1）（2）（3）</title>
        <author>sslaowan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sslaowan.javaeye.com">sslaowan</a>&nbsp;
          链接：<a href="http://sslaowan.javaeye.com/blog/173732" style="color:red;">http://sslaowan.javaeye.com/blog/173732</a>&nbsp;
          发表时间: 2008年03月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <strong>广州出差生活日记（1）</strong><br /> <br />2008-03-16 20:57<br /> 我们一行六人在3月14号来到广州，开始了广州港集团业务系统调研任务。<br /><br />  前几天一直杂事锁身，今天上午开了个战前准备汇报全会，总算可以喘息一下了。<br /><br />  话说在出差前夜，俺写下一篇日志，抒发了出差前夜的复杂心情，而这几天果然验证了我的部分兴奋之情。在火车上，我们突然发现我们六个人竟然正好有三个金牛座，三个处女座的人，这俩星座皆属土系星座，那叫一个“配”~或曰很好很和谐。于是乎我们在火车都要做翻天了，一车厢的人都认识我们了，还被上铺的大四小mm误以为我们是大四的，我说我们要是跟人家说我们是研究生估计人家得感叹现在这研究生素质咋这样。我们的话题始于艳照门，那是着实精彩的谈话节目啊~~之后我们打扑克，输了的人通过抽签选择参加真心话大冒险游戏，问题之生猛让人汗颜，和宪哥的节目相比真是有过之而无不及。大冒险多少有些收敛，无非就是向同车厢的少妇要手机号码，在车厢里大喊周杰伦我爱你云云~~<br /><br />   到了广州后，马上去了新家，那叫一兴奋，去了之后老佛爷就开始给我们分配任务，打扫房间，洗洗衣机（这个很搞笑），收拾床，搞得跟新房一样，我和大叔潜伏于厨房之中，开始煮盘子，擦冰箱，把房东几年不用的厨房擦了个遍，我和大叔都有个毛病，看不得东西有一半擦了一半没擦，这可是挺累。<br /><br />   今天上午开会那阵势不小，在悦海酒店一楼的会议室里围坐，活像一个IT公司开会，10台笔记本排开，很有气势。各个小组轮番发言，黄老师一一提问，本来以为很简单的业务需求，说起来都变得非常复杂，我和文文经过昨天云里雾里的总结，终于清晰起来的思路，又经受了沉重一击，话说有一叫做计费的模块，那叫一复杂，不同公司，不同货物，不同工具，都有不同的算法和规则，即使这样还有总经理直接下令这样的“超逻辑”业务逻辑。不过这也很激发我的兴趣，这可是领域驱动开发，面向对象绝好的表现机会啊~~这么复杂的系统如何用一套可迭代可进化的领域模型表示，优雅的与问题域映射，是巨大的挑战。除了我和文文负责的商务部分，我也仔细的听了计划，作业，仓库，工资，报表等部分，发现我们的领域模型覆盖了我见过的计划，运输，财务，交易，工资等《分析模式》《敏捷软件开发》《领域驱动开发》书中讲述的内容，就都有了实践~~今天元给我看了AMQ实现的IM，做的还挺好玩的~JPort一期工程就剩安全部分了（Acegi和LDAP）。<br /><br />    今天晚上和元合作，除了Pair Programming，我们还Pair Cooking，在条件极其苛刻的情况下（用盘子当菜板，用水果刀切肉切菜，用奶锅煮饭），完成了一顿晚餐~~老佛爷和靖还很给面子，吃了不少~~元真是个好男人~~<br /><br />    有点头疼，在看消息中间件，跟元继续研究啦~~~<br /><br /><strong>广州出差生活日记（2）</strong><br /> <br />2008-03-17 21:23<br />今天早上起来，几个人都有这样的感觉：好像在广州已经度过很多天了~实际上才2天而已。看来是每天的生活太精彩了，一天发生的事情太多了~~<br /><br />   早上把昨天剩的两个菜合加上鸡蛋炒了饭——新什锦炒饭~~呵呵，感觉味道还不错~~高大叔，奎，靖儿都吃了~~<br /><br />   坐车去新港调研，对方也是热情接待。今天真是上了一堂生动的社会课。一进会议室，对方就说随便坐，我们就特实在的随便坐了，结果被对方的一个阿姨批评说：你们老师还没坐呢你们怎么坐了呢？然后就给我讲：应该让领导先坐，然后坐在领导周围，还可以开玩笑说，领导您坐了，我们就找到坐标了~~黄老师当时也一愣，中午吃饭的时候黄老师说，你们以后到单位了真得注意这点，我们平时也不分，我也不在乎这些，但是工作了就不行了。我们听了都频频点头。上午我和王老师还有靖儿在业务部的办单中心，让他们的工作人员给我们讲解了费收系统的用法，真的很感谢他们的配合。我再次感受到了信息系统完全是一把手工程，我虽然没有参加动员大会，但是也有所耳闻，会上黄老师和他们集团的老总都讲了很重的话，说一定要配合。可是某些人真是虚与委蛇，在领导面前又是表态又是奉承，然后我们要资料时就说这个要保密，不能给我们真实的数据。或许是我资历浅，真有这规则，可是我调研过的该集团其他分公司可都没有这样的说法啊~<br /><br />    中午吃饭我们学乖了，吃了一顿特别累的饭。上来的第一道菜一定要是领导吃第一口，叫做剪彩。之后的每一道菜我都把它转到领导面前，然后再按顺时针转，这个问题很复杂。<br /><br />    晚上回来还真是累，下了车感觉累得不行了，都没有力气到外面吃饭了，可是回去做饭不是更累吗？在想未来工作了岂不是更辛苦，这要真找个不会做饭的老婆就麻烦了~~不过回去煮了点饺子，精神缓过来了，又继续投入了工作。<br /><br />  <br /><br />    我们实验室现在主题是：做饭。明天有更精彩的~~<br /><br />    下班了，明天再说~~<br /><br /><strong>广州出差生活日记（3）</strong> <br />2008-03-19 13:42<br />今天要写新的日记才发现，前两篇标了（1）和（2）的日志题目竟然有多处不同，一个叫《广州项目生活记录》一个叫《广州出差生活日记》。这篇还是延续上篇的名字，以后皆以此为标准。<br /><br /> <br /><br />   话说上文书最后留了个扣儿，说是有更精彩的内容在昨天发生。昨天到底如何了呢~嗯，黄老师、刘老师亲自下厨，跟我们共享了一顿家庭盛宴~下午文文她们去买菜就买了3个多小时，那叫一个多~我们从新港调研回来满以为可以吃上饭了，结果他们买菜还没有回来。文文她们住的地方好（读第二声，表示特别非常）大，无论是住屋还是厨房，抑或客厅。这个饭啊，基本上都是男生上灶，黄老师做了魭鱼（流程非常复杂），刘老师做了鸡翅和啤酒红烧肉。我们无非就是做些一般的家常炒菜，不过凑成了好大两桌子，有20来个菜，花费时间1个半小时，比我们料想的快多了。我们做饭时也是术语乱飞，买菜要先做个理货单，然后炒菜的时候刘老师成了Workflow Engine来调度和指挥做菜流程。伴着新闻联播的开始曲，大家开始围在一起吃饭，共同举杯，也不知道谁说了一句：庆祝十七大胜利闭幕。大家都说嗯，同祝同祝。黄老师突然来了一句：什么十七大啊，明明是人大十一届一次会议闭幕。我们都笑翻了，黄老师当时的语气和表情都恰到好处。<br /><br /> <br /><br />    昨天我们上午去新港调研，把计费系统的操作过程用录屏软件完全录制了下来，那个软件超diao，还可以同时录制声音。虽然问了很多低级问题，比如什么是内、外贸，进、出口，什么是船边，舱底，船舷，不过还是把流程都搞清楚了。<br /><br />    今天我们来碰了一下，重新看了一下去年的调研文档，发现他们的文档跟我们调研的差不多，我们自己写也就不过尔尔。这真是个矛盾，我们只看文档，的确看不懂，去问了一圈，就看懂了，而且觉得画的非常好，这每年都去问一次也受不了啊，这次我们录下来，再来的人放给他看，不知道能不能更快的理解，不过我们还是没法录下他们拿着纸质单证的样子，有些部分还是有些单证，如果加上个摄像机进行拍摄，做成一个片子，那就好了~~不知道哪家咨询公司会这样去做~~<br /><br /> <br /><br />    昨晚发现我们六个住在一起，特点是总有人莫名其妙的会自Hi，突然大笑。其实听阿奎说话看阿奎的表情我就想笑，还有老佛爷的表情，都觉得特好玩。晚上看电视，先是看《探索发现》，许亮和阿奎一个劲地在那讨论里面演得哈勃理论，什么宇宙大爆炸之类的，佛爷都要崩溃了。我说我们的话题终于摆脱了那种内容了。后来看《奋斗》，忽然争论起应不应该为了真爱而去破坏别的情侣，阿奎的观点一直是如果喜欢，就不要管对方是不是已经有男女朋友，也不要在乎自己有没有男女朋友，遭到了所有人的反对，我们都感叹阿奎的观念太先进了。后来我和高大叔就躲进小屋了，许亮一会也进来了，说了句阿奎正在舌战群妇（老佛爷和靖儿）~超级搞笑。<br /><br /> <br /><br />    今早起来，我又做了蛋炒饭，嗯，明早该换换了。唉，快成家庭主男了~昨晚老高给我打电话我正在做饭就按掉了，后来我给他发短信解释，他还说不信。晚上跟小路发短信说我们的六人行超爽生活，提及做饭，她也不信。唉，瞧不起人~~目前能把家常菜做熟，而且不咸不淡，可以吃，下一步得进行更深入的学习了，做饭很有意思，就像编程一样，我把它当成一种艺术（本人在音乐方面的缺陷造成了我对艺术青年的畅想很强烈，想把喜欢的东西都变成艺术创造，而且金牛座特别适合从事艺术行业）。<br /><br /> <br /><br />    生活就是这样，我爱生活~~~
          <br/>
          <span style="color:red;">
            <a href="http://sslaowan.javaeye.com/blog/173732#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 19 Mar 2008 13:49:44 +0800</pubDate>
        <link>http://sslaowan.javaeye.com/blog/173732</link>
        <guid>http://sslaowan.javaeye.com/blog/173732</guid>
      </item>
      <item>
        <title>出差前复杂的心情</title>
        <author>sslaowan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sslaowan.javaeye.com">sslaowan</a>&nbsp;
          链接：<a href="http://sslaowan.javaeye.com/blog/170692" style="color:red;">http://sslaowan.javaeye.com/blog/170692</a>&nbsp;
          发表时间: 2008年03月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 出差的心情真是好复杂，忙着收拾东西的时候倒不发觉，只是静下来会想，有期待，有懊恼，有担心，也有兴奋~~ <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这次出差一共12个人，第一波6人已经于上周日起程，次日到达，为我们选了房子，据文文说那是相当的好啊，还有DVD，全自动洗衣机~~~辛苦先头部队了，又是洗衣服被褥，又是帮我们买生活用品，用文文的话说跟置备了个家一样。嗯，每次出差都住招待所，而这次是住租的民宅，两室一厅，男生一室，女生一室，还蛮有意思的。哈哈，会是像Friends一样的生活吗？我们刚好都是六人行，两套房子，每边6个人。想想以前出去春游，醒来时看到披头散发的女生，哈欠连连的男生，或者发呆拿着牙刷刷牙，或者排在卫生间外等着上厕所，真是有意思。可是那都是短暂的时间，最长不过一周，可是我们要一起生活1个半月，还真是有意思~~~所以很<span><span style="font-size: large; color: #008000"><strong>期待</strong></span></span>这一段前所未有的出差旅程~~ <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可是我刚刚办了健身卡，就通知我出差，唉，今天上午给我和小路的美女会籍顾问打电话，说要延期一个月，真是<span style="font-size: large; color: #993300"><strong>无奈</strong></span>啊。想当初我是满心期待，准备大干一场，变成型男，可是一下子泡汤了~~唉，真是懊恼啊~~不过还好，到了广州也可以锻炼，团队中超多喜欢打篮球的，正好凑成六个人，我当然只能自己去玩了，这也是我要自带篮球的原因，不许跟我抢！！！ <br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这次出差的一个多月，正好是我们上课的一个半月，数学，英语，真让人担心。数学很难，上课我就没听懂过；今天去跟英语老师请假，可是她拒收假条，还说什么点名她还是会记下谁没来，超过5次就不用考试了，也不知道是真的还是开玩笑。出差会很忙，我们是否有空学习呢？好<span style="font-size: large; color: #0000ff"><strong>担心</strong></span>会挂掉唉，那真是晚节不保啊 <br /><br />今天我的pair元哥告诉我他的最新成果，据说使用AMQ搞出来个聊天工具，发给我源代码，可是还是有些问题。他说盼着我去广东呢，哈，等我来吧~~还有我们伟大的JPort计划，今天看Contributing to Eclipse，再次感受Kent和Gamma的合作，真是好唉~~这次出差让我很兴奋的是，有个合作了4年的，超级默契的Partern&mdash;&mdash;文文&mdash;&mdash;跟我一起做需求，有个超级好的老大&mdash;&mdash;宋博士&mdash;&mdash;领导俺们，还有一个充满激情，技术又很厉害的pair&mdash;&mdash;元哥&mdash;&mdash;跟我pair program，还有实验室几个活宝mm，搞笑的高大叔，阿奎，勇哥，相信这次差旅会别有情趣~~从上学期开始，我们实验室的Team就始终战斗在一起，真是羡煞了其他老师，总是能看到张老师深情地看着我们这群人在一起讨论业务，讨论技术，非常激烈，在白板上边画边说，还有定期的技术和业务培训，实验室成为了我的又一个家（另一个家是广播站~）。还有可以见到阿达，也不知道小衰神又有啥变化没，呵呵~~想想这些就好<span style="font-size: large; color: #ff0000"><strong>兴奋</strong></span>，真想一下子就飞到广州，跟他们会合~~ <br /><br />貌似有点小激动，带来点小失眠，北京晚安，广州早安~~我要出发啦~~ <br /><p>&nbsp;</p>
          <br/>
          <span style="color:red;">
            <a href="http://sslaowan.javaeye.com/blog/170692#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 13 Mar 2008 00:12:39 +0800</pubDate>
        <link>http://sslaowan.javaeye.com/blog/170692</link>
        <guid>http://sslaowan.javaeye.com/blog/170692</guid>
      </item>
      <item>
        <title>关于现在架构的一个图示</title>
        <author>sslaowan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sslaowan.javaeye.com">sslaowan</a>&nbsp;
          链接：<a href="http://sslaowan.javaeye.com/blog/163174" style="color:red;">http://sslaowan.javaeye.com/blog/163174</a>&nbsp;
          发表时间: 2008年02月18日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这张图并非我们架构的全貌，是团队中一个成员对于我们设计的架构的理解，我补充上了远程外观与本地外观的连接和VO，这个图画的很有意思，他也是看了UML和模式应用学会了将白板上画的草图用数码相机照下来，然后供以后查阅。虽然这张图并不是我们架构的全貌，某些部分是出于他的理解而有所简化，但是这张画在白板上的图还是蛮有意思的~~
          <br/>
          <span style="color:red;">
            <a href="http://sslaowan.javaeye.com/blog/163174#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 18 Feb 2008 21:15:20 +0800</pubDate>
        <link>http://sslaowan.javaeye.com/blog/163174</link>
        <guid>http://sslaowan.javaeye.com/blog/163174</guid>
      </item>
      <item>
        <title>项目组内部推荐书目</title>
        <author>sslaowan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sslaowan.javaeye.com">sslaowan</a>&nbsp;
          链接：<a href="http://sslaowan.javaeye.com/blog/162239" style="color:red;">http://sslaowan.javaeye.com/blog/162239</a>&nbsp;
          发表时间: 2008年02月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p align="center" style="text-align: center"><strong><span style="font-size: 22pt; font-family: 宋体">项目组内部推荐书目</span></strong></p><p align="center" style="text-align: center">&nbsp;</p><p align="center" style="text-align: center">零雨其蒙</p><p align="center" style="text-align: center"><span style="font-size: 12pt">2008</span><span style="font-size: 12pt; font-family: 宋体">年</span><span style="font-size: 12pt">2</span><span style="font-size: 12pt; font-family: 宋体">月</span></p><h1><span style="font-family: 宋体">前言</span></h1><p style="text-indent: 21.75pt"><span style="font-family: 宋体">本文介绍理解本项目所有架构、设计思想和具体技术、工具使用的著作，阅读以下著作，可以更好的理解我们的项目为何如此架构，为什么要使用这些工具，以及过去在项目中出现的文档中所简单描述的内容的背后原理是什么。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">学会使用工具是很容易的，但是知道为何要使用这些工具以及如何进行企业信息系统的设计是非常困难的。因此，阅读书籍首先要明确自己的学习目标，然后按照本文的分类去阅读将比较容易而不至于被如此之多的知识淹没。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">比如你可以先学会使用</span>Eclipse<span style="font-family: 宋体">，</span>SSH<span style="font-family: 宋体">框架开发一个小的只包含</span>CRUD<span style="font-family: 宋体">操作的网站</span>Demo<span style="font-family: 宋体">，然后再去理解</span>SSH<span style="font-family: 宋体">是如何解决企业应用中必须要解决的问题的，阅读</span>Fowler<span style="font-family: 宋体">的《企业应用架构模式》是最好的起点，了解哪些问题是企业应用必需要解决的问题，并发处理是大型企业应用必然会遇到而在开发桌面应用程序不会遇到的，而且也是在单元测试阶段最不容易发现问题的。因此仔细阅读这一部分是非常必要的，包括线程的并发访问，数据库并发访问使用数据库事务（数据库提供了怎样的隔离机制和锁机制，如何设置隔离级别，以达到效率和安全的平衡）和业务事务（</span>J2EE<span style="font-family: 宋体">环境下如何使用两阶段提交来解决这一问题和对于长事务使用离线锁模式。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">同时你可以通过编写这个</span>Demo<span style="font-family: 宋体">对于</span>Java<span style="font-family: 宋体">有个认识，并与已经学习过的语言建立联系。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">但必须要明确学习目标，做</span>Demo<span style="font-family: 宋体">就是为了学会使用</span>SSH<span style="font-family: 宋体">和</span>Java<span style="font-family: 宋体">，而非为了掌握设计和架构思想。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">本文所推荐的书籍就是目前项目使用的架构和开发方法论的参考书籍，因此如果想要全面理解项目使用的架构、技术和开发方法论，做到知其然并知其所以然必须认真阅读以下图书，这是一个最简集，当然很多思想还来自于其他书籍和实践经验。</span></p><p style="text-indent: 21.75pt">PS<span style="font-family: 宋体">：我花了一年时间阅读这些书籍，某些图书在我的</span>Blog<span style="font-family: 宋体">上有读书笔记，大家可以参考我的读书笔记阅读原著，因为毕竟我们有相似的经历，我想我当时遇到的困惑也可能是大家会遇到的困惑。</span></p><p style="text-indent: 21.75pt">Blog<span style="font-family: 宋体">：</span><a href="http://www.blogjava.net/sslaowan"><span style="color: #1d58d1">www.blogjava.net/sslaowan</span></a></p><span style="font-family: 宋体"><p style="text-indent: 21.75pt"><span style="font-family: 宋体">书目：</span></p><p style="margin-left: 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt">1、&nbsp;<span style="font-family: 宋体">架构</span></p><p style="margin-left: 42.8pt; text-indent: 5.65pt; tab-stops: list 42.75pt"><span style="color: red">1)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span></span><span style="color: red; font-family: 宋体">企业架构应用模式</span><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Martin Fowler</span><span style="color: red; font-family: 宋体">著</span></p><p style="margin-left: 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt">2、&nbsp;<span style="font-family: 宋体">需求分析</span></p><p style="margin-left: 42.8pt; text-indent: 5.65pt; tab-stops: list 42.75pt"><span style="color: red">2)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span></span><span style="color: red; font-family: 宋体">编写有效用例</span><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Cockburn</span><span style="color: red; font-family: 宋体">著</span></p><p style="margin-left: 42.8pt; text-indent: 5.65pt; tab-stops: list 42.75pt">3)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">有效用例模式</span>&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Steve Adolph<span style="font-family: 宋体">著</span></p><p style="margin-left: 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt">3、&nbsp;<span style="font-family: 宋体">面向对象分析</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt"><span style="color: red">4)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="color: red; font-family: 宋体">分析模式：可复用的对象模型</span><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Martin Fowler</span><span style="color: red; font-family: 宋体">著</span></p><p style="margin-left: 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt">4、&nbsp;<span style="font-family: 宋体">面向对象设计</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt"><span style="color: red">5)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="color: red">UML</span><span style="color: red; font-family: 宋体">和模式应用（原书第</span><span style="color: red">3</span><span style="color: red; font-family: 宋体">版）</span><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Craig Larman</span><span style="color: red; font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">6)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">对象设计：角色、责任和协作</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Wirfs-Brock<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">7)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">领域驱动设计：软件核心复杂性解决之道</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Eric Evans<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt"><span style="color: red">8)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span style="color: red; font-family: 宋体">敏捷软件开发：原则、模式与实践</span><span style="color: red">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Robert Martin</span><span style="color: red; font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">9)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Object Primer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Scott W.Ambler<span style="font-family: 宋体">著</span></p><p style="margin-left: 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt">5、&nbsp;<span style="font-family: 宋体">软件工程与敏捷开发</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">10)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">敏捷软件开发生态系统</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;Jim Highsmith<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">11)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">解析极限编程：拥抱变化（第</span>2<span style="font-family: 宋体">版）</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Kent Beck<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">12)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">代码大全</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;McConnel<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">13)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">重构：改善既有代码的设计</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Marin Fowler<span style="font-family: 宋体">著</span> </p><p style="margin-left: 39.75pt; text-indent: -18pt; tab-stops: list 39.75pt">6、&nbsp;<span style="font-family: 宋体">技术：</span>Java<span style="font-family: 宋体">和</span>J2EE</p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">14)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>Agile Java&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Jeff Langr<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">15)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>Contribute to Eclipse&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Kent Beck<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">16)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>J2EE<span style="font-family: 宋体">设计开发编程指南</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Rod Johnson<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">17)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>Expert One-on-One J2EE Development without EJB&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;Rod Johnson<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">18)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>Spring<span style="font-family: 宋体">框架高级编程</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;Rod Johnson<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">19)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>J2EE<span style="font-family: 宋体">核心模式</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Deepak Alur<span style="font-family: 宋体">等著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">20)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>Struts in Action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ted Husted<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">21)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>JUnit in Action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a href="http://www.china-pub.com/search/power_search/power_search.asp?key1=Vincent+Massol%2c+Ted+Husted" target="_blank"><span style="color: windowtext; text-decoration: none; text-underline: none">Vincent Massol</span></a><span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">22)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">使用</span>Ant<span style="font-family: 宋体">进行</span>Java<span style="font-family: 宋体">开发</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;<a href="http://www.china-pub.com/search/power_search/power_search.asp?key1=Erik+Hatcher%2cSteve+Loughran" target="_blank"><span style="color: windowtext; text-decoration: none; text-underline: none">Erik Hatcher</span></a><span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">23)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>POJO in Action&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Richardson<span style="font-family: 宋体">著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">24)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span>Spring<span style="font-family: 宋体">从入门到精通</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">郭峰</span> &nbsp;&nbsp;<span style="font-family: 宋体">编著</span></p><p style="margin-left: 51pt; text-indent: -5.65pt; tab-stops: list 42.75pt">25)<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">敏捷</span>Acegi<span style="font-family: 宋体">、</span>CAS<span style="font-family: 宋体">－构建安全的</span>Java<span style="font-family: 宋体">系统</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">罗时飞</span> <span style="font-family: 宋体">编著</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">本文介绍的图书会比这个书目稍多一些。红色标注的图书是理解架构，进行系统分析设计的必读读物。</span></p></span><h1><span style="font-family: 宋体">软件开发综述类</span></h1><p>&nbsp;&nbsp; <span style="font-family: 宋体">建议首先阅读本分类中的图书，以对项目整个使用的方法的全貌有个总体了解。</span></p><p>&nbsp;&nbsp; <span style="font-family: 宋体">对于软件开发过程的综述，包括对于</span>UML<span style="font-family: 宋体">，模式，面向对象，迭代方法，敏捷</span>UP<span style="font-family: 宋体">的讨论，</span>Martin Fowler<span style="font-family: 宋体">在多部著作中推荐了</span>Larman<span style="font-family: 宋体">的<strong>《</strong></span><strong>UML</strong><strong><span style="font-family: 宋体">和模式应用（第三版）》</span></strong><span style="font-family: 宋体">，其中介绍了完整的从需求分析（用例，补充说明书，</span>SSD<span style="font-family: 宋体">，操作契约），领域建模，到面向对象设计（</span>RDD<span style="font-family: 宋体">，</span>GRASP<span style="font-family: 宋体">，</span>GoF<span style="font-family: 宋体">设计模式）的敏捷的迭代过程，其中也讲解了各种实战中的</span>UML<span style="font-family: 宋体">的画法。另外一本</span>Ambler<span style="font-family: 宋体">的<strong>《</strong></span><strong>Object Primer</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">，也是讲述敏捷语境下的面向对象技术，其风格更加严肃，不过对于业务规则，用户界面，持久化等的讨论可以作为</span>Larman<span style="font-family: 宋体">的著作的补充。</span></p><h1><span style="font-family: 宋体">需求分析类</span></h1><p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">建议首先阅读</span>Larman<span style="font-family: 宋体">的著作，以便了解需求分析并不只是依靠用例，然后编写用例的必读书目是</span>Cockburn<span style="font-family: 宋体">的<strong>《编写有效用例》</strong>，之后可阅读<strong>《有效用例模式》</strong>。</span></p><p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">还有一本讲述<strong>业务规则</strong>的图书对于理解业务流程等概念很有帮助，如果你像我一样想明确区分业务流程，工作流，领域逻辑，业务逻辑等概念，因为这对于如何组织系统架构的分层具有重大意义。</span></p><h1><span style="font-family: 宋体">面向对象分析</span></h1><p style="text-indent: 21.75pt"><span style="font-family: 宋体">建议阅读</span>Martin Fowler<span style="font-family: 宋体">的<strong>《分析模式：可复用对象模型》</strong>，里面关于库存和财务，交易，计划，组织结构模式，测量，观察模式的讨论，对于为我们的项目建模有一定指导作用。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">另外</span>Eric Evans<span style="font-family: 宋体">的<strong>《领域驱动设计：软件核心复杂性解决之道》</strong>也是一本好书，其对于实体，值对象和服务的讨论对于理解项目架构思想很有帮助。</span></p><h1><span style="font-family: 宋体">面向对象设计</span></h1><p style="text-indent: 21.75pt"><span style="font-family: 宋体">建议阅读</span>Robert Martin<span style="font-family: 宋体">的<strong>《敏捷软件开发：原则，模式和实践》</strong>，其</span>Java/C++<span style="font-family: 宋体">版，和</span>C#<span style="font-family: 宋体">版同样具有帮助，其中对于</span>OCP<span style="font-family: 宋体">，</span>DIP<span style="font-family: 宋体">，</span>SRP<span style="font-family: 宋体">等</span>OOD<span style="font-family: 宋体">原则的讨论非常深入透彻，对于</span>GOF<span style="font-family: 宋体">设计模式的讲解和其他相关模式的摄入都对于理解什么是面向对象设计，以及怎样的设计才是正确的非常有帮助。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">对于如何发现对象和为对象分配职责这一问题，除了阅读</span>Larman<span style="font-family: 宋体">和</span>Ambler<span style="font-family: 宋体">的书之外，</span>Wirfs-Brock<span style="font-family: 宋体">编写的<strong>《对象设计：角色，责任和协作》</strong>是对这一问题的深入讨论，其中的诸多方法如角色构造型，和对于责任，角色，协作的充分讨论，对于帮助找到解决之道很有帮助。</span></p><h1>J2EE<span style="font-family: 宋体">架构</span></h1><p style="text-indent: 21pt"><span style="font-family: 宋体">对于信息系统架构和设计的权威著作是</span>Martin Fowler<span style="font-family: 宋体">的<strong>《企业应用架构模式》</strong>，它可以帮助你理解你所熟悉的和不熟悉的架构、设计决策背后隐藏的原理。其对于分层架构，领域建模，并发控制（线程和事务，锁机制），数据持久化策略（包括数据访问接口，实体关系映射等）等的讨论都很清晰，对于理解项目中的分层结构，建立领域模型，</span>O/R<span style="font-family: 宋体">映射及其他架构模式的运用的动机有更为深入的理解。配合<strong>《</strong></span><strong>POJO In Action</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">（该书是建立在</span>Fowler<span style="font-family: 宋体">的《企业应用架构模式》，</span>Evans<span style="font-family: 宋体">的《领域驱动设计》和</span>Johnson<span style="font-family: 宋体">的《</span>J2EE without EJB<span style="font-family: 宋体">》等著作的基础上写的，你可以自己决定阅读顺序），有助于了解在敏捷</span>J2EE<span style="font-family: 宋体">架构下如何应用这些模式，其中使用了</span>Spring<span style="font-family: 宋体">，</span>Hibernate<span style="font-family: 宋体">框架，与我们的项目最为接近。</span></p><p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">建议阅读<strong>《</strong></span><strong>J2EE</strong><strong><span style="font-family: 宋体">核心模式》</span></strong><span style="font-family: 宋体">，本书是</span>Sun<span style="font-family: 宋体">公司编写的，描述了实战中的</span>J2EE<span style="font-family: 宋体">项目使用的模式，项目中使用的很多模式来自于该书，虽然最有用的部分在</span>Fowler<span style="font-family: 宋体">的书中已经有阐述，但是直接在</span>J2EE<span style="font-family: 宋体">语境下进行讨论还是有必要的，然而<strong>《</strong></span><strong>POJO in Action</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">的出现，多少对此削弱了一些。</span></p><p>&nbsp;&nbsp;&nbsp;&nbsp; Struts+Spring+Hibernate<span style="font-family: 宋体">的入门快速上手书籍可参看郭峰的<strong>《</strong></span><strong>Spring</strong><strong><span style="font-family: 宋体">从入门到精通》</span></strong><span style="font-family: 宋体">。</span> <span style="font-family: 宋体">主要阅读控制反转和依赖注入，声明式事务处理，持久化处理（使用</span>JdbcTemplate<span style="font-family: 宋体">和整合</span>Hibernate<span style="font-family: 宋体">）。其他类似书籍所讲内容大抵相同，所以建议参看其中一本快速入门，更深入的讨论请阅读</span>Johnson<span style="font-family: 宋体">的<strong>《</strong></span><strong>Spring</strong><strong><span style="font-family: 宋体">高级编程指南》</span></strong><span style="font-family: 宋体">。</span></p><p>&nbsp;&nbsp;&nbsp;&nbsp; Spring<span style="font-family: 宋体">方面的书籍最好按顺序阅读</span>Rod Johnson<span style="font-family: 宋体">（他是</span>Spring<span style="font-family: 宋体">之父）的三部巨著<strong>《</strong></span><strong>J2EE</strong><strong><span style="font-family: 宋体">设计开发编程指南》《</span>J2EE without EJB</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">和<strong>《</strong></span><strong>Spring</strong><strong><span style="font-family: 宋体">高级编程指南》</span></strong><span style="font-family: 宋体">，对于全面理解</span>Spring<span style="font-family: 宋体">的使用动机，设计原理和最佳实践会有一个深入的理解。其中充分讨论了企业应用应该注意的问题，</span>J2EE<span style="font-family: 宋体">经典架构的问题，应该如何对待</span>EJB<span style="font-family: 宋体">，以及更好的替代</span>EJB<span style="font-family: 宋体">的方案是什么，为什么他们是更好的。这对于理解项目中为什么使用这些技术作了最为深刻的讲解。而</span>Spring<span style="font-family: 宋体">的开发手册可作为一个速查的手册（主要阅读依赖注入，声明式事务处理，持久化，安全，远程访问等章节）。实践中的</span>Spring<span style="font-family: 宋体">请参阅<strong>《</strong></span><strong>POJO in Action</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">等图书。</span></p><p>&nbsp;&nbsp;&nbsp;&nbsp; Hibernate<span style="font-family: 宋体">的权威之作无疑是<strong>《</strong></span><strong>Hibernate in Action</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">，是</span>Hibernate<span style="font-family: 宋体">之父写的，里面充分的讲解了持久化的最佳实践，不过没有中文版，其缩略版是</span>Hibernate<span style="font-family: 宋体">开发手册，可以看这个作为速查，关于事务，持久化，锁等可以参阅</span>Fowler<span style="font-family: 宋体">和</span>Johnson<span style="font-family: 宋体">的书，也可以参看《</span>POJO in Action<span style="font-family: 宋体">》。</span></p><p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">关于</span>Struts<span style="font-family: 宋体">，建议阅读<strong>《</strong></span><strong>Struts in Action</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">。</span></p><p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">项目中用到的其他技术还包括：</span>RCP<span style="font-family: 宋体">客户端，其中主要使用的</span>Eclipse<span style="font-family: 宋体">核心架构，在这里推荐阅读</span>Kent Beck<span style="font-family: 宋体">和</span>Gamma<span style="font-family: 宋体">写的《</span>Contribute to Eclipse<span style="font-family: 宋体">》，</span>Gamma<span style="font-family: 宋体">是</span>Eclipse<span style="font-family: 宋体">的首席架构师，本书详细的讲解了</span>Eclipse<span style="font-family: 宋体">架构中所用的设计模式和设计思想，对于插件架构的讲解对于我们编写</span>RCP<span style="font-family: 宋体">客户端大有帮助。没有任何一本</span>Eclipse<span style="font-family: 宋体">的书籍可以代替本书的价值。阅读本书的意义在于帮助你设计客户端程序，而关于一些基本的知识（如</span>JFace<span style="font-family: 宋体">，</span>SWT<span style="font-family: 宋体">）请参考</span>RCP<span style="font-family: 宋体">编写的专门书籍（中国人写的目前好像只有一本），另外也可参考《</span>Agile Java<span style="font-family: 宋体">》。</span></p><p style="text-indent: 21.75pt">jBPM<span style="font-family: 宋体">工作流引擎请参阅</span>Spring<span style="font-family: 宋体">对于</span>jBPM<span style="font-family: 宋体">的扩展项目的文档，只有英文版。当然还要阅读</span>jBPM<span style="font-family: 宋体">的官方文档。一些通俗的例子请参见项目组内部文档。另外阅读</span>Fowler<span style="font-family: 宋体">的《企业应用架构模式》和一些工作流、业务流程管理的书籍对于理解工作流引擎大有裨益。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">对于</span>J2EE<span style="font-family: 宋体">安全管理部分可阅读</span>Johnson<span style="font-family: 宋体">的<strong>《</strong></span><strong>Spring</strong><strong><span style="font-family: 宋体">高级编程指南》</span></strong><span style="font-family: 宋体">。手把手入门教材是罗时飞编著的<strong>《敏捷</strong></span><strong>Acegi</strong><strong><span style="font-family: 宋体">、</span>CAS</strong><strong><span style="font-family: 宋体">－构建安全的</span>Java</strong><strong><span style="font-family: 宋体">系统》</span></strong><span style="font-family: 宋体">和</span>Acegi<span style="font-family: 宋体">的官方文档。而在实际项目中的安全管理和</span>Acegi<span style="font-family: 宋体">的使用请参考</span>JavaEye<span style="font-family: 宋体">（</span>www.javaeye.com<span style="font-family: 宋体">）的一些讨论和文章。</span></p><h1>Java<span style="font-family: 宋体">与</span>J2EE</h1><p>&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">推荐阅读<strong>《</strong></span><strong>Agile Java</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">，其采用测试驱动开发的方式讲解</span>Java<span style="font-family: 宋体">的基础知识，是目前我所见过的最能读下去的</span>Java<span style="font-family: 宋体">图书。作为速查可以找一本计算机二级复习用书。最为权威的著作是<strong>《</strong></span><strong>Core Java2</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">，不过更象是</span>API<span style="font-family: 宋体">手册。最为深邃的图书是<strong>《</strong></span><strong>Thinking in Java</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">和<strong>《</strong></span><strong>Effective Java</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">，对于</span>Java<span style="font-family: 宋体">有深入了解可以仔细看看。</span></p><p>&nbsp;&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">另外找一本专业的</span>J2EE<span style="font-family: 宋体">图书，里面会详细讲解</span>JSP<span style="font-family: 宋体">，</span>Servlet<span style="font-family: 宋体">，</span>JNDI<span style="font-family: 宋体">，</span>JDBC<span style="font-family: 宋体">之类的原理和用法，建议选用和</span>IBM Webshpere<span style="font-family: 宋体">或</span>BEA Weblogic<span style="font-family: 宋体">无关的</span>J2EE<span style="font-family: 宋体">图书和有关的</span>J2EE<span style="font-family: 宋体">图书各一本。</span></p><h1><span style="font-family: 宋体">数据库</span></h1><p style="text-indent: 21.75pt"><span style="font-family: 宋体">建议至少阅读《</span>Oracle DBA<span style="font-family: 宋体">入门手册》，真正理解</span>Oracle<span style="font-family: 宋体">的优化配置，</span>SQL<span style="font-family: 宋体">语句的正确写法，序列，索引，触发器，函数，数据库模式设计以及并发处理等主题。</span></p><h1>Unix</h1><p>&nbsp;&nbsp;&nbsp; <span style="font-family: 宋体">建议阅读一本</span>AIX<span style="font-family: 宋体">的专著，以理解</span>Unix<span style="font-family: 宋体">操作系统的基本原理和使用方法。</span></p><h1><span style="font-family: 宋体">敏捷开发</span></h1><p style="text-indent: 21.75pt"><span style="font-family: 宋体">关于极限编程，推荐阅读</span>Kent Beck<span style="font-family: 宋体">（他是极限编程的创始人）写的<strong>《解析极限编程：拥抱变化（第</strong></span><strong>2</strong><strong><span style="font-family: 宋体">版）》</span></strong><span style="font-family: 宋体">，以帮助你理解我们项目所采用的结对编程，测试驱动开发，重构，用户故事等实践及其背后的原理。对于如何在敏捷环境下做计划，本书的讨论应该在加上</span>Kent<span style="font-family: 宋体">和</span>Fowler<span style="font-family: 宋体">合著的<strong>《规划极限编程》</strong>才更完整。制定计划是非常重要的，同样控制过程，检验计划完成情况更加重要。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">对于敏捷开发更全面的理解来自于</span>Jim Highsmith<span style="font-family: 宋体">的<strong>《敏捷软件开发生态环境》</strong>，其中讨论了极限编程，</span>ASD<span style="font-family: 宋体">，</span>FDD<span style="font-family: 宋体">，</span>DSDM<span style="font-family: 宋体">等敏捷方法。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">关于为何不使用瀑布模型而使用迭代方法请参看</span>Larman<span style="font-family: 宋体">的《</span>UML<span style="font-family: 宋体">和模式应用》，</span>Fowler<span style="font-family: 宋体">的</span><strong><em>New Methodology</em></strong><span style="font-family: 宋体">，</span>McConnell<span style="font-family: 宋体">的<strong>《代码大全》</strong>。其中</span>Larman<span style="font-family: 宋体">和</span>McConnell<span style="font-family: 宋体">都在书中引入了大量实验数据来说明这一问题。瀑布模型在国际上公认出自于</span>Winston W.Royce<span style="font-family: 宋体">博士于</span>1972<span style="font-family: 宋体">年发表的论文《</span>Managing the Development of Large Software Systems<span style="font-family: 宋体">》，但是该论文实际上是反对瀑布模型的。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">在项目中会使用一些极限编程实践工具，如重构，</span>JUnit<span style="font-family: 宋体">，</span>Ant<span style="font-family: 宋体">等，请参考阅读以下书籍：</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">关于重构的最权威的讨论来自</span>Martin Fowler<span style="font-family: 宋体">的<strong>《重构：改善既有代码的设计》</strong>，</span>Eclipse<span style="font-family: 宋体">中的重构功能中使用的重构名即出自此书，其对于代码坏味道的总结对于避免团队成员写出糟糕的代码有很好的指导作用；而其对于重构方法的讨论非常细致，步骤很清晰，幸运的是工具已经代替你做这些容易出错而又细致的步骤，你只需要理解在何种情况应该使用什么重构法即可。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">关于</span>JUnit<span style="font-family: 宋体">的最好且最简单的著作是<strong>《</strong></span><strong>JUnit in Action</strong><strong><span style="font-family: 宋体">》</span></strong><span style="font-family: 宋体">，项目中组织测试的经验即来自本书。由于项目采用</span>J2EE<span style="font-family: 宋体">和测试驱动开发，因此本书是必读书籍。</span></p><p style="text-indent: 21.75pt"><span style="font-family: 宋体">关于</span>Ant<span style="font-family: 宋体">的最全面的讨论是《<strong>使用</strong></span><strong>Ant</strong><strong><span style="font-family: 宋体">进行</span>Java</strong><strong><span style="font-family: 宋体">开发</span></strong><span style="font-family: 宋体">》。其中对于持续集成的讨论对于实践这一理论很有帮助，然而对于持续集成更全面的讨论来自于</span>Fowler<span style="font-family: 宋体">的文章</span><strong><em>Continuous Integration</em></strong><span style="font-family: 宋体">。</span></p>
          <br/>
          <span style="color:red;">
            <a href="http://sslaowan.javaeye.com/blog/162239#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 14 Feb 2008 15:19:35 +0800</pubDate>
        <link>http://sslaowan.javaeye.com/blog/162239</link>
        <guid>http://sslaowan.javaeye.com/blog/162239</guid>
      </item>
      <item>
        <title>企业应用架构模式——笔记（2）</title>
        <author>sslaowan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://sslaowan.javaeye.com">sslaowan</a>&nbsp;
          链接：<a href="http://sslaowan.javaeye.com/blog/161087" style="color:red;">http://sslaowan.javaeye.com/blog/161087</a>&nbsp;
          发表时间: 2008年02月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          by 零雨其蒙 <p>2008-1-29</p><h3>1.1.1<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">关系的映射</span></h3><p><span style="font-family: 宋体">对象和关系处理连接的方式不同，会造成两大问题：</span></p><p>1<span style="font-family: 宋体">、表现方法不同：</span></p><p style="text-indent: 21pt">a<span style="font-family: 宋体">、<strong>对象</strong>是通过在运行时（内存管理环境或内存地址）中保存引用的方式来处理连接；</span></p><p style="text-indent: 21pt">&nbsp;&nbsp; public class A{</p><p style="text-indent: 21pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private B b;</p><p style="text-indent: 21pt">}</p><p style="text-indent: 21pt">&nbsp;A<span style="font-family: 宋体">和</span>B<span style="font-family: 宋体">的连接，通过在</span>A<span style="font-family: 宋体">的实例</span>a<span style="font-family: 宋体">中保存的</span>B<span style="font-family: 宋体">的实例</span>b<span style="font-family: 宋体">建立。</span></p><p style="text-indent: 21pt">b<span style="font-family: 宋体">、<strong>关系数据库</strong>则通过创建到另外一个表的键值来处理连接。</span></p><p style="text-indent: 21pt">&nbsp;<span style="font-family: 宋体">表</span>A<span style="font-family: 宋体">中保存表</span>B<span style="font-family: 宋体">的</span>ID<span style="font-family: 宋体">，作为</span>A<span style="font-family: 宋体">的外键，来建立</span>A<span style="font-family: 宋体">和</span>B<span style="font-family: 宋体">的连接。</span></p><p>2<span style="font-family: 宋体">、对象可以很容易的通过集合来表示多个引用。</span></p><p>&nbsp;&nbsp; <span style="font-family: 宋体">规范化则要求所有的关系连接都必须是单值。</span></p><p><strong><span style="font-family: 宋体">解决办法：</span></strong><span style="font-family: 宋体">通过对象中的一个</span><span style="font-family: 楷体_GB2312">标识域</span><span style="font-family: 宋体">来保持每个对象的关系特性，并且通过查找这些值来保持对象引用和关系键之间的互相映射。</span></p><h3>1.1.2<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">继承</span></h3><p><span style="font-family: 宋体">三种模式：单表继承，具体表继承，类表继承。</span></p><table cellspacing="0" border="1" style="border-collapse: collapse; border: medium none" cellpadding="0"><tbody><tr><td valign="top" style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 142pt; padding-top: 0cm; border: windowtext 1pt solid" width="189">&nbsp;</td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 142.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p><span style="font-family: 宋体">优点</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 142.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p><span style="font-family: 宋体">缺点</span></p></td></tr><tr><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 142pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p><span style="font-family: 宋体">单表继承</span></p><p><span style="font-family: 宋体">（为继承体系中所有类建立一个统一的表）</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 142.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p><span style="font-family: 宋体">把所有内容放到一起</span></p><p>a<span style="font-family: 宋体">、这样修改起来容易</span></p><p>b<span style="font-family: 宋体">、并且避免了</span>join<span style="font-family: 宋体">操作</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 142.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p>1<span style="font-family: 宋体">、浪费空间，因为每一行都必须为每种可能的子类保留一些类，导致很多空类。</span></p><p>2<span style="font-family: 宋体">、它的大小将成为访问的瓶颈。</span></p></td></tr><tr><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 142pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p><span style="font-family: 宋体">具体表继承</span></p><p><span style="font-family: 宋体">（为继承体系中每个具体类建立一张表）</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 142.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p><span style="font-family: 宋体">避免</span>join<span style="font-family: 宋体">操作，效率高</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 142.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p>1<span style="font-family: 宋体">、改变困难</span></p><p style="text-indent: 10.5pt">a<span style="font-family: 宋体">、对超类的任何改变都不得不改变所有表（还有映射代码）</span></p><p style="text-indent: 10.5pt">b<span style="font-family: 宋体">、改变层次结构自身会带来更大的改变</span></p><p>2<span style="font-family: 宋体">、缺乏超类表</span></p><p style="margin-left: 10.5pt">a<span style="font-family: 宋体">、使主键管理十分可怕</span></p><p style="margin-left: 10.5pt">b<span style="font-family: 宋体">、引用完整性也有问题</span></p></td></tr><tr><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 142pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p><span style="font-family: 宋体">类表继承</span></p><p><span style="font-family: 宋体">（为继承体系中每个类创建一张表）</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 142.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p><span style="font-family: 宋体">简单</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 142.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="189"><p><span style="font-family: 宋体">使用多个</span>join<span style="font-family: 宋体">操作载入一个对象，会损失性能</span></p></td></tr></tbody></table><p>Fowler<span style="font-family: 宋体">倾向于使用单表继承：因为易于实现和重构。</span></p><h3>1.1.3<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp; </span><span style="font-family: 宋体">建立映射</span></h3><p style="text-indent: 11.25pt">Fowler<span style="font-family: 宋体">建议：首先使用领域建模，然后在不超过六个月的迭代中建立数据库模型。</span></p><p style="text-indent: 11.25pt"><span style="font-family: 宋体">如果领域设计和数据库表同构有意义，则考虑使用</span><strong><span style="font-family: 楷体_GB2312">活动记录</span></strong><span style="font-family: 宋体">代替。（原文：</span>If a database design isomorphic to the <a href="mk:@MSITStore:G:/"><span style="color: #1d58d1">Domain Model</span></a> (116) makes sense, you might consider an <a href="mk:@MSITStore:G:/"><span style="color: #1d58d1">Active Record</span></a> (160) instead.<span style="font-family: 宋体">）</span></p><div style="padding-right: 4pt; padding-left: 4pt; background: #ccffcc; padding-bottom: 1pt; margin-left: 21.6pt; margin-right: 0cm; padding-top: 1pt; border: green 1pt solid"><p style="background: #ccffcc; tab-stops: 21.6pt; border: medium none; padding: 0cm"><strong><span style="font-family: 宋体">零雨其蒙注解</span></strong><span style="font-family: 宋体">：</span>isomorphic<span style="font-family: 宋体">，同构指的应该是结构相同，比如</span>Employee<span style="font-family: 宋体">类和</span>Employee<span style="font-family: 宋体">表拥有相同的属性</span>/<span style="font-family: 宋体">字段。</span></p></div><h1>2<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;Web<span style="font-family: 宋体">表现层</span></h1><p>MVC<span style="font-family: 宋体">中</span>M<span style="font-family: 宋体">是指领域模型。</span></p><div style="padding-right: 4pt; padding-left: 4pt; background: #ccffcc; padding-bottom: 1pt; margin-left: 21.6pt; margin-right: 0cm; padding-top: 1pt; border: green 1pt solid"><p style="background: #ccffcc; tab-stops: 21.6pt; border: medium none; padding: 0cm"><strong><span style="font-family: 宋体">零雨其蒙注解</span></strong><span style="font-family: 宋体">：当然，看</span>Larman<span style="font-family: 宋体">的</span><em>UML</em><em><span style="font-family: 宋体">和模式应用</span></em><span style="font-family: 宋体">中介绍是，原来模型是指数据模型，后来成立领域模型。</span></p></div><h2>2.1<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span><span style="font-family: 黑体">输入控制器模式</span></h2><p>MVC<span style="font-family: 宋体">中的控制器：</span></p><p><span style="font-family: 宋体">一种理解为&ldquo;输入控制器&rdquo;，主要作用为：</span></p><p>1<span style="font-family: 宋体">、从请求消息流中读取数据</span></p><p>2<span style="font-family: 宋体">、将业务逻辑传递给一个合适的领域对象</span></p><p>3<span style="font-family: 宋体">、将返回的数据放到</span>HTTP<span style="font-family: 宋体">会话（</span>Session<span style="font-family: 宋体">）对象中，与视图共享。</span></p><p><span style="font-family: 宋体">第二种理解为&ldquo;应用控制器&rdquo;，主要作用为：</span></p><p><span style="font-family: 宋体">处理应用程序流，决定视图应该按什么顺序出现。</span></p><p>Fowler<span style="font-family: 宋体">对输入控制器的结论，更为准确地说法是为每个动作准备一个</span><span style="font-family: 楷体_GB2312">页面控制器</span><span style="font-family: 宋体">（</span><em>Page Controller</em><span style="font-family: 宋体">）。</span></p><div style="padding-right: 4pt; padding-left: 4pt; background: #ccffcc; padding-bottom: 1pt; margin-left: 21.6pt; margin-right: 0cm; padding-top: 1pt; border: green 1pt solid"><p style="background: #ccffcc; tab-stops: 21.6pt; border: medium none; padding: 0cm"><strong><span style="font-family: 宋体">零雨其蒙注解</span></strong><span style="font-family: 宋体">：应用控制器负责处理页面流程。</span>Struts<span style="font-family: 宋体">的</span>Aciton<span style="font-family: 宋体">是页面控制器（除了包含输入控制器功能外，还负责创建视图对象</span>FormBean<span style="font-family: 宋体">），</span>ActionServlet<span style="font-family: 宋体">是前端控制器，负责解释</span>URL<span style="font-family: 宋体">来判断调用哪个页面控制器。配置文件起到应用控制器的作用。</span></p></div><h2>2.2<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span><span style="font-family: 黑体">视图模式</span></h2><p style="text-indent: 31.5pt">A two-stage view (<a href="mk:@MSITStore:G:/"><span style="color: #1d58d1">Figure 4.3</span></a>) breaks this process into two stages, producing a logical screen from the domain data and then rendering it in HTML. There's one first-stage view for each screen but only one second-stage view for the whole application.</p><div style="padding-right: 4pt; padding-left: 4pt; background: #ccffcc; padding-bottom: 1pt; margin-left: 21.6pt; margin-right: 0cm; padding-top: 1pt; border: green 1pt solid"><p style="background: #ccffcc; tab-stops: 21.6pt; border: medium none; padding: 0cm"><strong><span style="font-family: 宋体">零雨其蒙注解</span></strong><span style="font-family: 宋体">：</span><span style="font-family: 楷体_GB2312">两步视图</span><span style="font-family: 宋体">中的第一步逻辑屏幕应该是指</span>View Object<span style="font-family: 宋体">或者是</span>Struts<span style="font-family: 宋体">中</span>FormBean<span style="font-family: 宋体">这种东西，第二步应该是使用相应的自动化程序将其变成</span>HTML<span style="font-family: 宋体">或者是</span>Swing<span style="font-family: 宋体">客户端，在</span>Sturts<span style="font-family: 宋体">中应该就是</span>Struts<span style="font-family: 宋体">自己的类，它可以将数据渲染（</span>rendering<span style="font-family: 宋体">）成</span>HTML<span style="font-family: 宋体">页面。</span></p></div><h1>3<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">并发</span></h1><p><span style="font-family: 宋体">并发造成的问题：</span></p><p>1<span style="font-family: 宋体">、更新丢失。</span>A<span style="font-family: 宋体">读取了一张表中的数据，然后对其修改。这时</span>B<span style="font-family: 宋体">也读取了该表中的数据，修改后将其保存。这时</span>A<span style="font-family: 宋体">才修改完，将其保存。这样</span>A<span style="font-family: 宋体">就覆盖了</span>B<span style="font-family: 宋体">的修改。</span></p><p>2<span style="font-family: 宋体">、不一致读。</span></p><p><span style="font-family: 宋体">并发涉及到两个层面：</span></p><p>1<span style="font-family: 宋体">、客户端访问应用服务器，使用线程或进程，一个进程中可包含多个线程，线程使用共享内存，这样就会造成并发问题。</span></p><p>2<span style="font-family: 宋体">、访问数据库，这会涉及到事务，并发访问数据库。</span></p><p><span style="font-family: 宋体">系统事务：发生在应用程序到数据库之间</span></p><p><span style="font-family: 宋体">业务事务：发生在用户到应用程序之间</span></p><p><span style="font-family: 宋体">解决并发的两种方式：</span></p><p>1<span style="font-family: 宋体">、隔离</span></p><p>2<span style="font-family: 宋体">、不变性</span></p><p><strong><span style="font-family: 宋体">预防死锁！</span></strong></p><p><strong>2008-1-30</strong></p><h2>3.1<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span><span style="font-family: 黑体">事务</span></h2><p style="margin-left: 28.8pt"><strong><span style="font-family: 宋体">在企业应用中处理并发最主要的工具是事务。</span></strong><br /></p><p style="margin-left: 28.8pt"><span style="font-family: 宋体">事务：</span>1<span style="font-family: 宋体">、事务是一个有边界的工作序列，开始和结束都有明确定义</span></p><p style="margin-left: 28.8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<span style="font-family: 宋体">、所有相关资源在事务开始和结束时都保持一致。</span></p><p style="margin-left: 28.8pt">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3<span style="font-family: 宋体">、每个事务都必须保证要么全部完成，要么什么都不做。</span></p><p style="text-indent: 21pt">ACID<span style="font-family: 宋体">：</span></p><p style="text-indent: 21pt"><span style="font-family: 宋体">原子性：</span></p><p style="text-indent: 21pt"><span style="font-family: 宋体">一致性：在事务开始和完成的时候，系统地资源都必须处于一致的，没有被破坏的状态。比如一个人买啤酒，虽然少了钱，但是得到了等价值的啤酒，其拥有的总资产不变。</span></p><p style="text-indent: 21pt"><span style="font-family: 宋体">隔离性：一个事务，直到它被成功提交之后，它的结果对于任何其他的事务才是可见的。</span></p><p style="text-indent: 21pt"><span style="font-family: 宋体">持久性：一个已提交的事务的任何结果都必须是永久性的，即&ldquo;在任何系统崩溃的情况下都能保存下来&rdquo;。</span></p><p style="text-indent: 21.1pt"><strong><span style="font-family: 宋体">事务资源：</span></strong><span style="font-family: 宋体">在技术讨论时，使用事务资源表示进行事务处理的任何事物&mdash;&mdash;即使用事务来控制并发过程。</span></p><p style="text-indent: 21.1pt"><strong><span style="font-family: 宋体">长事务</span></strong><span style="font-family: 宋体">：跨越多个请求的事务叫长事务</span></p><p style="text-indent: 21pt"><span style="font-family: 宋体">几种<strong>不一致读</strong>的情况：</span></p><p style="text-indent: 21.1pt"><strong><span style="font-size: 10.5pt; font-family: 宋体">脏读：</span></strong><span style="font-size: 10.5pt">脏读是指事务A访问并修改了一个数据，但还没有提交回表中，这时事务B访问并使用了该数据，则事务B读到的可能就是一个&ldquo;脏&rdquo;的数据。依据脏数据所作的操作就很可能是错误的。</span></p><p style="text-indent: 21.1pt"><strong><span style="font-size: 10.5pt; font-family: 宋体">不可重复读：</span></strong><span style="font-size: 10.5pt">不可重复读是指事务A对某数据进行一次读取后，数据被事务B访问并修改。当事务A再一次访问数据时，会发现跟前一次读到的数据不一致。</span></p><p style="text-indent: 21.1pt"><strong><span style="font-size: 10.5pt; font-family: 宋体">幻读：</span></strong><span style="font-size: 10.5pt">幻读是指当事务不是独立执行时发生的一种现象。例如事务A对一个表中的数据进行了修改，这种修改涉及到表中的全部数据行。同时，事务B也修改这个表中的数据，这种修改是向表中插入一行新数据。那么，操作事务A的用户就会发现表中还有未修改的数据行，就好象发生了幻觉一样。</span></p><p style="margin-left: 21pt"><strong><span style="font-size: 10.5pt">不可重复读</span></strong><span style="font-size: 10.5pt">的重点是修改: <br />同样的条件,你读取过的数据,再次读取出来发现值不一样了 <br /><strong>幻读的</strong>重点在于新增或者删除 <br />同样的条件,第1次和第2次读出来的记录数不一样</span></p><p style="text-indent: 21pt"><span style="font-size: 10.5pt">几个<strong>隔离级别</strong>：</span></p><p style="text-indent: 21.1pt"><strong><span style="font-size: 10.5pt">读未提交：</span></strong><span style="font-size: 10.5pt">意思就是说，允许用户<strong>读</strong>取其他用户<strong>未提交</strong>的事务中修改的数据。比如B修改了数据D（比如从2改成了1，此时D被修改了，成了脏数据），但是还没有提交，在这种隔离级别下，数据库允许此时A读取数据D（即允许<strong>脏读</strong>），读完显示给A后，B做修改的事务回滚了，也就是修改实际上没有完成，那么A读到的数据D（值为1）就不是真实的情况（应该还是为2）。这时A对数据D进行操作，就可能出现错误，比如将D（商品价格）*0.8（折扣）然后保存到另一张表（比如是用户订单）中，那么就保存了一个错误的结果。</span></p><p style="text-indent: 21.1pt"><strong><span style="font-size: 10.5pt">读已提交</span></strong><span style="font-size: 10.5pt">：意思就是说，数据库允许用户<strong>读</strong>取其他用户<strong>已</strong>经<strong>提交</strong>的事务中修改的数据。允许<strong>不可重复读</strong>这种不一致的情况发生。这样允许事务A未提交时，事务B对A已读到的数据进行修改。但是事务A读到的数据一定是已经提交的数据（因此不可能出现脏读），而在读未提交隔离级别下，可以读未提交的数据。</span></p><p style="text-indent: 21.1pt"><strong><span style="font-size: 10.5pt">可重复读</span></strong><span style="font-size: 10.5pt">：锁定查询中使用的所有数据以防止修改（避免脏读和不可重复读），但是不防止插入数据，这时重新读取时，就会读到之前没读到的数据，出现了<strong>幻读</strong>。此隔离级别允许出现幻读。Fowler：这种幻读出现在你向一个集合添加一部分元素而读的人只能读到其中一部分的时候。</span></p><p style="text-indent: 21.1pt"><strong><span style="font-size: 10.5pt">可序列化</span></strong><span style="font-size: 10.5pt">：实际上是独占方式读取数据。</span></p><p style="text-indent: 21pt"><span style="font-size: 10.5pt">隔离级别与所允许的不一致读：</span></p><table cellspacing="0" border="1" style="width: 100%; border-collapse: collapse; border: medium none" width="100%" cellpadding="0"><tbody><tr><td valign="top" style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 25%; padding-top: 0cm; border: windowtext 1pt solid" width="25%"><p><strong><span style="font-size: 10.5pt">隔离级别</span></strong></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><strong><span style="font-size: 10.5pt">脏读</span></strong></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><strong><span style="font-size: 10.5pt">不可重复读</span></strong></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25.02%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><strong><span style="font-size: 10.5pt">幻读</span></strong></p></td></tr><tr><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><strong><span style="font-size: 10.5pt">读未提交&nbsp;&nbsp; </span></strong></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">是</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">是</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25.02%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">是</span></p></td></tr><tr><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><strong><span style="font-size: 10.5pt">读已提交</span></strong></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">否</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">是</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25.02%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">是</span></p></td></tr><tr><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><strong><span style="font-size: 10.5pt">可重复读</span></strong></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">否</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">否</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25.02%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">是</span></p></td></tr><tr><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><strong><span style="font-size: 10.5pt">可序列化</span></strong></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">否</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">否</span></p></td><td valign="top" style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 25.02%; padding-top: 0cm; border-bottom: windowtext 1pt solid" width="25%"><p><span style="font-size: 10.5pt">否</span></p></td></tr></tbody></table><p style="text-indent: 21pt"><span style="font-size: 10.5pt">2008-1-31</span></p><h2>3.2<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span><span style="font-family: 黑体">离线并发控制的模式</span></h2><p><span style="font-family: 宋体">处理<strong>业务事务</strong>的模式</span></p><p><span style="font-family: 宋体">乐观离线锁</span></p><p><span style="font-family: 宋体">悲观离线锁</span></p><h2>3.3<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </span><span style="font-family: 黑体">应用服务器并发</span></h2><p style="text-indent: 21pt"><span style="font-family: 宋体">应用服务器自身的进程并发，这里不涉及事务。</span></p><p style="text-indent: 21pt"><span style="font-family: 宋体">最简单的处理办法是使用<strong>每会话一进程</strong>，就是每个会话都在自己的进程中运行。<strong>问题是</strong>：大量资源的耗费，因为进程是昂贵的。可以通过进程池来提高利用率，这时每个进程在一个时刻只处理单个请求，但可以在时间序列上处理来自不同会话的多个请求。<strong>问题是</strong>：必须保证每个请求结束时都释放其占用的所有资源。</span></p><p style="text-indent: 21.1pt"><strong><span style="font-family: 宋体">每会话一线程</span></strong><span style="font-family: 宋体">，即在一个进程中运行多个线程来进一步提高吞吐率。每次请求由进程中的某个线程处理。</span></p><h1>4<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">会话状态</span></h1><p>Fowler<span style="font-family: 宋体">建议：</span></p><p>1<span style="font-family: 宋体">、倾向于使用服务器会话状态模式，特别是在以下情况下：</span></p><p>&nbsp;&nbsp; a<span style="font-family: 宋体">、备忘文件被远程存储以备系统在服务器崩溃之后仍能恢复</span></p><p>2<span style="font-family: 宋体">、使用会话状态模式来存放会话标识号和数据量较小的会话。</span></p><p>3<span style="font-family: 宋体">、我个人并不喜欢数据库会话状态模式，建议只在以下三种情况使用</span></p><p style="text-indent: 11.25pt">a<span style="font-family: 宋体">、需要故障恢复和集群时</span></p><p style="text-indent: 11.25pt">b<span style="font-family: 宋体">、无法存储远程备忘文件时</span></p><p style="text-indent: 11.25pt">c<span style="font-family: 宋体">、不关心会话间数据隔离时</span></p><h1>5<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">分布策略</span></h1><p><span style="font-family: 宋体">分布式对象第一定律：不要分布使用对象。（大多数情况下使用集群）</span></p><p><strong>2008-2-1</strong></p><h1>6<span style="font: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-family: 宋体">通盘考虑</span></h1><p>Core J2EE<span style="font-family: 宋体">分层模型</span></p><table cellspacing="0" border="1" style="border-collapse: collapse; border: medium none" cellpadding="0"><tbody><tr><td valign="top" style="padding-right: 5.4pt; padding-left: 5.4pt; background: black; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; border: black 1pt solid" width="284"><p><strong>Core J2EE</strong></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: black 1pt solid; padding-left: 5.4pt; background: black; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><strong>Fowler</strong></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">客户层层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">运行于客户端的表现层（如</span>Java<span style="font-family: 宋体">客户端）</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">表现层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">运行于服务器端的表现层（如</span>HTTP<span style="font-family: 宋体">处理程序，服务器页面（</span>Java Server Page<span style="font-family: 宋体">））</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">业务层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">领域层</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">集成层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">数据源层）</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">资源层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">需要与数据源层通信的外部资源</span></p></td></tr></tbody></table><p>Marinescu<span style="font-family: 宋体">分层模型</span></p><table cellspacing="0" border="1" style="border-collapse: collapse; border: medium none" cellpadding="0"><tbody><tr><td valign="top" style="padding-right: 5.4pt; padding-left: 5.4pt; background: black; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; border: black 1pt solid" width="284"><p><strong>Marinescu</strong></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: black 1pt solid; padding-left: 5.4pt; background: black; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><strong>Fowler</strong></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">表现层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">表现层</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">应用层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">表现层（应用控制器）</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">服务层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">领域层（服务层）</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">领域层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">领域层（领域模型）</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">持久层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">数据源层</span></p></td></tr></tbody></table><p><strong><span style="font-family: 宋体">服务层</span></strong><span style="font-family: 宋体">将<strong>工作流逻辑</strong>从<strong>纯粹领域逻辑</strong>中剥离出来。服务层所包含的逻辑一般都特定于某个用例，并与其他一些基础设施相互通信。（</span>Fowler<span style="font-family: 宋体">个人认为这种分离偶尔有用，但一般情况下没用）</span></p><p>Mircosoft DNA<span style="font-family: 宋体">分层模型</span></p><table cellspacing="0" border="1" style="border-collapse: collapse; border: medium none" cellpadding="0"><tbody><tr><td valign="top" style="padding-right: 5.4pt; padding-left: 5.4pt; background: black; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; border: black 1pt solid" width="284"><p><strong>Mircosoft DNA</strong><strong><span style="font-family: 宋体">分层模型</span></strong></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: black 1pt solid; padding-left: 5.4pt; background: black; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><strong>Fowler</strong></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">表现层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">表现层</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">业务层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">领域层</span></p></td></tr><tr><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: black 1pt solid; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">数据访问层</span></p></td><td valign="top" style="border-right: black 1pt solid; padding-right: 5.4pt; border-top: medium none; padding-left: 5.4pt; padding-bottom: 0cm; border-left: medium none; width: 213.05pt; padding-top: 0cm; border-bottom: black 1pt solid" width="284"><p><span style="font-family: 宋体">数据源层</span></p></td></tr></tbody></table><p>DNA<span style="font-family: 宋体">中的记录集实际上充当一种各层的</span><span style="font-family: 楷体_GB2312">数据传输对象</span><span style="font-family: 宋体">（</span>DTO<span style="font-family: 宋体">）。业务层能够根据自己的方式修改</span><span style="font-family: 楷体_GB2312">记录集</span><span style="font-family: 宋体">，