﻿<?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-e世纪-文章分类-软件构架</title><link>http://www.blogjava.net/bill2004158/category/28582.html</link><description>－－科技是第一生产力</description><language>zh-cn</language><lastBuildDate>Thu, 03 Jan 2008 00:59:55 GMT</lastBuildDate><pubDate>Thu, 03 Jan 2008 00:59:55 GMT</pubDate><ttl>60</ttl><item><title>白话软件架构与架构师  </title><link>http://www.blogjava.net/bill2004158/articles/172039.html</link><dc:creator>Bill Wang</dc:creator><author>Bill Wang</author><pubDate>Tue, 01 Jan 2008 15:45:00 GMT</pubDate><guid>http://www.blogjava.net/bill2004158/articles/172039.html</guid><wfw:comment>http://www.blogjava.net/bill2004158/comments/172039.html</wfw:comment><comments>http://www.blogjava.net/bill2004158/articles/172039.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bill2004158/comments/commentRss/172039.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bill2004158/services/trackbacks/172039.html</trackback:ping><description><![CDATA[<span class="f14"><font size="3">架构一词是舶来品，是architecture的中文翻译, 其英文的本意是来源于建筑行业的建筑艺术、建筑（风格）和结构，引入到软件领域里面来以后，并没有一个统一的定义。有的人将架构定义为：功能+设计+构造手段，我们可以通俗的理解为：总体设计和总体结构。<br />
<br />
买过房子的人都知道5层以下的楼房一般是砖混结构，而高层和小高层的楼房都是框架结构，楼层越高对结构要求越高。软件也是一样，系统越庞大，生命周期越
长，结构的重要性就越明显。因此，随着人们对软件工程的深刻理解，将架构进行充分的强调是很自然的，正如人们越来越强调系统的需求分析，从而有了领域工程
师和领域专家的概念一样。其实强调软件架构的最主要的目的有3个：<br />
<br />
重用：人们希望系统能够重用以前的代码和设计，从而提高开发效率；<br />
<br />
扩展：人们希望在系统能够保持结构的稳定的前提下很容易地扩充功能和性能，希望能够&#8220;以静制动&#8220;；<br />
<br />
简洁：常言道，简洁就是美，好的架构一定易于理解，易于学习，易于维护，人们希望能够通过一个简洁的架构来把握系统； <br />
<br />
正如我们可以很简单地用砖混结构和框架结构来概括一幢大楼的结构，专家们也定义了一些术语来定义软件的架构风格，如层次结构、B/S结构等。软件架构设
计是软件设计的一部分，是其中的总体设计。软件的架构设计有一定的创造性，但它毕竟是一个工程活动，架构的设计是有章可循的，有一定的规律性的，是可以重
复的，有其稳定的模式。当然，在系统一开始很难可以建立一个完善的稳定的架构。迭代是软件开发过程中必然的一个过程，这是人的思维活动的一个必然阶段。
<br />
<br />
软件架构师实际上就是软件的总体设计师。首席设计师就是总设计师，打个通俗的比方：邓小平是中国改革开放的总设计师，我们用现在的说
法可以讲，邓小平是中国改革开放的首席架构师。架构师的形成一定是在实践中积累起来的，而并非上了几次培训班，读了几本书就可以成功的，架构师是在工程实
践中培养出来的！ <br />
架构师也并非是万能的。架构师是客户需求和开发者之间的桥梁。在软件行业中，一般提到的架构师是技术架构师，而忽略了领域架
构师或者讲是领域工程师的概念。一个好的领域专家一定是业务领域的架构师，他能够给出某一个业务领域的架构，我们可以称为业务架构，只有技术架构和业务架
构紧密结合才有可能真正创造出一个好的系统！ </font></span>
<p></p>
<span class="f14">
<h2><a id="viewpost.ascx_TitleUrl" href="http://blog.csdn.net/arielxp/archive/2005/03/11/317389.aspx"><font color="#223355">软件架构之面向对象技术</font></a> </h2>
<p>
<table align="center" border="0" cellpadding="0" cellspacing="0" width="590">
    <tbody>
        <tr>
            <td><span class="f14"><font size="3">
            面向对象编程语言包括Smalltalk、 C++、
            Java编程语言和C#（微软.Net开发环境中提供的一种语言）。这些语言按照抽象数据类型（通常称为类）的要求支持数据和操作代码的封装。在面向对象
            编程语言中，封装能力对于适度大小的程序是足够的。只要软件模块由单独的程序员维护，封装对于提供一些内在的优点就是完全足够的。但是，特定语言的封装不
            足以支持软件的重复使用和分布式系统。<br />
            <br />
            在面向对象技术中，基本范例被改变为允许关系的分离。图1显示了面向对象技术的范式，在它里面
            程序被分成叫做对象（object）的更小的片段。每个对象都包含了系统的一些数据，并且程序封装了这些数据。换句话说，只有通过使用与该数据直接相关的
            程序才能访问这些数据。通过这种方法，系统被分离成独立改变的模块。数据表现的任何改变仅仅影响封装该数据的直接的对象。<br />
            <br />
            对象使用消息彼此通讯。消息可能影响状态——换句话说就是改变数据——但是只能通过与本地数据密切相关的封装了的过程来改变它。对于小程序，对象范式对于隔离改变来说是有效的。但是，这个范式对于所有可能的使用情形来说并不是完美的。<br />
            <br />
            现在面向对象技术已经被广泛地使用了。一般来说程序上的技术来自于学术界，但是面向对象技术事实上来自于商业组织。实际上面向对象技术有很多有趣的渊
            源，甚至于可以追溯到计算机科学的开端。现在对象技术是占有统治地位的商业软件范式。事实上每个软件生产商都提供了对象技术的解决方案，并一起提供了组件
            的下部构造，允许不同软件环境中的软件厂商之间交互操作。<br />
            <br />
            <strong>面向对象的架构</strong><br />
            <br />
            对于主要的软件开发从业者来说，面向对象是缺乏软件架构方法的。在面向对象的方法和文化中，这种缺乏在很多方面都有表现。从通常被当作原始来源的<em>OO</em>（面向对象）思考、<em>设计面向对象软件</em>【Wirfs-Brock
            1990】开始，已经有了软件架构的概念，包括通过观察协作图（collaboration
            diagram，它需要一个章节才能讲清楚）发现子系统（subsystem）。在接下来的十年中，在面向对象方法学社团中几乎没有写出什么有关架构的东
            西。主要的<em>OO</em>方法学的书本中关于架构的章节都很少，它们都是Wirfs-Brock的架构概念的一些模糊的反映。<br />
            <br />
            由于实际上几乎没有关于架构的专著，大多数OO从业者都只有最基础的架构指导。他们没有理由认为架构很重要。这种态度导致OO项目中很大的混乱，因为小组成员必须尽全力去管理那些并非为他们设计的OO方法的复杂性和可伸缩性。<br />
            <br />
            一般而言，OO方法包含了成功的对象模型技巧，在这些模型中大多数分解对象最终被转换为编程对象。这种方法叫做基于模型（model-based）的方
            法。为了了解架构，认为每个分解对象都不可避免地成为编程对象是所有OO开发人员都需要克服的一个主要障碍。在架构模型中，特定对象表现约束而不是编程对
            象。它们可能会，也可能不会被转换成编程对象，这是由开发人员的自行的决定。<br />
            <br />
            OO也在其它一些微小的地方与架构矛盾，这与项目文化相关。OO鼓励项目小组平等，这样所有的决定都是民主的。在这样的项目中就没有架构的角色了，因为在开发小组的成员之间作出的决定的差别是很小的。<br />
            <br />
            OO鼓励开发中的&#8220;bad-is-better&#8221;思考方式，实际上这是一种与架构思想背离的哲学。使用bad-is-better思想的时候，任务实现的
            外部表现远远超过了可以维护的的内部结构的任何需求。换句话说，快速迭代的原型处理，以及对架构原理的无情的漠视对于OO开发来说是一种正常的、健康的环
            境。<br />
            <br />
            架构的话题只在最近的OO专著中与新发现的组件技术一起被重新提到的。现在大多数方法学的书本都习惯性地包含一个关于架构的象征
            性的章节，但是在OO的全盛时期，架构实际上是禁止使用的。从感觉上讲，组件是OO的缺点的反映。组件的强调较大&#8220;颗粒&#8221;的软件接口和模块，是向架构想法
            方向的改进步骤。<br />
            </font><strong><br />
            <font size="3">　　数据库和对象</font></strong><font size="3"> <br />
            <br />
            数据库技术也朝对象的方向演化。数据库技术源于几个不同的模型。近些年，数据库的关系模型是最有影响力的。到最近，面向对象的数据库已经成为重要的技术
            市场，而联合了面向对象和关系概念的数据库也很平常。大多数主要的行业数据库，例如Oracle 9i和IBM的DB2数据库都包含了对象－关系能力。<br />
            <br />
            数据库查询语言，例如结构化查询语言（SQL），都在标准的工作方面进行了扩展以支持面向对象的概念。发生这种情况的原因之一是人们正在建立的这类应用程序需要充分的、更多的适合显示需要的数据表现类型和查询算法类型以搜索和维护信息。<br />
            </font><strong><br />
            <font size="3">　　对象在主流技术中的地位</font></strong><font size="3"> <br />
            <br />
            目前对象技术应用于大多数应用程序范围和垂直的市场中。政府组织和工商企业正在用对象技术运作大量的项目。对象技术的主要优点是它允许为组织提供竞争优
            势的新业务流程的实现。社会正在朝不断依赖信息技术的方向转变。对象技术的使用通过软件重复使用机制允许快速的系统实现和各种形式的劳动力的节省。尽管大
            量的软件代码仍然存在于面向过程的语言（例如COBOL）中，但是很清楚这种范式正在改变。<br />
            </font><strong><br />
            <font size="3">　　脚本语言</font></strong><font size="3"> <br />
            <br />
            脚本语言的支持者声称使用脚本语言的编程人数比使用其它类型语言的编程人数都要多【Ousterhout
            1998】。脚本语言，例如JavaScript语言、TCL shell编程语言和Visual
            Basic语序可以把先前存在的软件（例如组件）轻易地集成到应用程序构造中去。</font></span></td>
        </tr>
    </tbody>
</table>
</p>
</span>
<img src ="http://www.blogjava.net/bill2004158/aggbug/172039.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bill2004158/" target="_blank">Bill Wang</a> 2008-01-01 23:45 <a href="http://www.blogjava.net/bill2004158/articles/172039.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>敏捷思维-架构设计中的方法学</title><link>http://www.blogjava.net/bill2004158/articles/172038.html</link><dc:creator>Bill Wang</dc:creator><author>Bill Wang</author><pubDate>Tue, 01 Jan 2008 15:43:00 GMT</pubDate><guid>http://www.blogjava.net/bill2004158/articles/172038.html</guid><wfw:comment>http://www.blogjava.net/bill2004158/comments/172038.html</wfw:comment><comments>http://www.blogjava.net/bill2004158/articles/172038.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bill2004158/comments/commentRss/172038.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bill2004158/services/trackbacks/172038.html</trackback:ping><description><![CDATA[<div><font size="3">方法论对软件开发而言意味着什么？我们如何看待软件开发中的方法论？方法论能够成为软件开发的救命稻草吗？在读过此文后，这些疑惑就会得到解答。</font></div>
<div><font size="3">在
第一篇文章中，我们来了解标题中的一些词的含义。方法学是什么？ 敏捷是什么？
为什么讨论架构？方法论方法论的英文为Methodology，词典中的解释为"A series of related methods or
techniques"我们可以把它定义为软件开发（针对软件开发）的一整套方法、过程、规则、实践、技术。关于方法论的出现的问题，我很赞同
Alistair
Cockburn的一句话，"方法论源于恐惧。"出于对项目的超期、成本失控等等因素的恐惧，项目经理们从以前的经验出发，制定出了一些控制、监测项目的
方法、技巧。这就是方法论产生的原因。在Agile Software
Development一书中，作者提到了方法论的十三个要素，基本能够函盖方法论的各个方面：角色（Roles） 个性（Personality）
技能（Skills） 团队（Teams） 技术（Techniques） 活动（Activities） 过程（Process） 工件（Work
products） 里程碑（Milestones） 标准（Standards） 质量（Quality） 工具（Tools） 团队价值（Team
Values）它们之间的关系可以用一幅图来表示：</font></div>
<div><font size="3">图 1. </font></div>
<div><font size="3">方
法论的十三个要素很多的方法论，都涉及了上面列举的十三要素中的部分要素，因此，我们可以把方法论看作是一个抽象的、无穷的超集，而现实中的方法论都是指
超集的一个有限的子集而已。它们之间的关系就好像有理数和1到100之间的整数的关系一样。不论是XP，还是UI设计经验之类，都属于方法论的一个子集，
只是这两个子集之间有大小的差别而已。我们还应该看到，讨论一个完备的方法论是没有意义的，因此这种方法论铁定不存在，就好像你视图穷举出所有的有理数一
样荒唐。因此，我们关于一个通用的方法论的说法也是无意义的。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">好
的方法论，比如说XP、水晶系列，它们都有一个适合的范围，因为它们了解一点，自己并不是一个无所不能的方法论。在现实中，我们其实不断的在接触方法论。
比如说，为了控制项目的进度，项目经理要求所有的开发人员每周递交一份详细的进度报告，这就是一种方法、一种技巧。如果把开发过程中的这些技巧系统的组织
起来，就能够成为一种方法论。你可能会说，那一种方法论的产生也太容易了吧。不，这样产生的方法论并没有太大的实用价值，没有实用价值的方法论根本就没有
存在的必要。因此，一个成功的方法论是要能够为多个的项目所接受，并且能够成功实现软件的交付的方法论。我和我的同事在实践中做了一些试验，希望能够把一
些好的方法论应用于开发团队。试验的结果很无奈，方法论实施的效果并不理想，一开始我们认为是方法本身的原因，到后来，我们发现事情并不是这么简单。在试
验的过程中，开发人员一致认同方法论的优势所在，但是在实施过程中，鲜有坚持的下来的。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">在Agile
Software Development中，我发现作者遇到了和我们一样的问题。 Alistair
Cockburn在和大量的项目团队的访谈之后，写成了Agile Software
Development一书。在访谈之前，他笃定自己将会发现高度精确的过程控制是成功的关键所在，结果他发现事实并非如此，他把他的发现归结为7条定
律。而我在实际中的发现也包含在这七条定律中，总结起来就只有两点：沟通和反馈。只要能够保证良好的沟通和即时的反馈，那么开发团队即使并没有采用先进的
方法论，一样可以成功。相反，那些"高质量"的团队却往往由于缺乏这两个因素而导致失败（我们这里指的失败是用户拒绝使用最终的软件）。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">最
有效，而成本也最低的沟通方法就是面对面（face to
face）的沟通，而随着项目团队的变大，或是另外一些影响因素的加入（比如地理位置的隔绝），面对面的沟通越来越难实现，这导致沟通的的成本逐渐加大，
质量也慢慢下降。但这并不是说非面对面的沟通不可，重要的是我们需要知道不同的沟通方式的成本和质量并不相同。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">XP
方法尤为强调面对面的沟通，通过现场客户、站立会议、结对编程等方式来保证沟通的有效。在我的经验中，一个开发团队其实是需要多种沟通方式的结合的。完全
的面对面的沟通对某些团队来说是很难实现的，那么问题的关键就在于你如何应用沟通的方式来达到你希望的效果。在前不久结束的欧莱雅创业计划大赛上，有一支
团队特别引人注目，他们彼此间素未谋面，仅仅凭借Internet和电话完成了高效的合作。他们虽然没有使用面对面的沟通方式，但是仍然达成了既定的目
标。软件开发也是一样的，面对面的沟通是非常有必要的，但其它的沟通方式也是需要的。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">再
看反馈，不论是控制进度，还是保证客户的满意度，这些活动都需要管理成本。软件开发中的管理成本的一个通性就是伴随有中间产出物
（intermediate
delivery）。比如说我们的需求规约、分析文档、设计文档、测试计划，这些都属于中间产出物。中间产出物的增加将会带来效率下降的问题，因为开发人
员的时间都花在了完成中间产出物的工作上，花在给软件新功能上的时间就减少了。而中间产出物的主要目的是两个，一个是为了保证软件如客户所愿，例如需求规
约；另一个是为了作为团队中的其他成员工作的输入，例如开发计划、测试计划等。因此，我们也可以针对这两点来商讨对策，一种是采用迭代的思想，提高软件发
布的频率，以保证客户的需求被确实的满足，另一种就是缩小团队的沟通范围，保证成员能够从其他人那里得到新的思路，而不是撰写规范的内部文档（内部文档指
那些仅为内部开发人员之间的沟通所需要的文档）。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">因
此，一个软件项目的成功和你采用的开发方法论并没有直接的关系。重量我们根据把拥有大量artifact（RUP官方翻译为工件，意思是软件开发过程中的
中间产物，如需求规约、设计模型等）和复杂控制的软件开发方法称为重型（Heavy
Weight）方法，相对的，我们称artifact较少的方法为轻型（Light Weight）方法。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">在传统的观念中，我们认为重型方法要比轻型安全许多。因为我们之所以想出重型方法，就是由于在中大型的项目中，项目经理往往远离代码，他无法有效的了解目前的工程的进度、质量、成本等因素。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">为了克服未知的恐惧感，项目经理制定了大量的中间管理方法，希望能够控制整个项目，最典型的莫过于要求开发人员频繁的递交各种表示项目目前状态的报告。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">在Planning
XP一书中有一段讨论轻重型方法论的精辟论述，它把重型方法论归结为一种防御性的姿态（defensive
posture），而把轻型方法论归结为一种渴望成功（Plan to
win）的心态。如果你是采用了防御性姿态，那么你的工作就集中在防止和跟踪错误上，大量的工作流程的制定，是为了保证项目不犯错误，而不是项目成功。而
这种方法也不可谓不好，但前提是如果整个团队能够满足前面所提到的两个条件的话，项目也肯定会成功，但是重型方法论的一个弊端就在于，大家都在防止错误，
都在惧怕错误，因此人和人之间的关系是很微妙的，要达到充分的沟通也是很难的。最终，连对人的评价也变成是以避免错误的多寡作为考评的依据，而不是成就。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我们在做试验的时候，一位项目经理开玩笑说，"方法论源自项目经理的恐惧，这没错。但最糟糕的是整个团队只有项目经理一个人恐惧，如果能够做到人人的恐惧，那大家也就没有什么好恐惧的了。"</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">这句话提醒了我们，如果一个团队的精神就是力求成功，那么这支团队的心态就和其它的团队不同了，尤其是对待错误的心态上。根本就没有必要花费大量的精力来预防错误，错误犯了就犯了，即时改正就可以了。这其实就是渴望成功的心态。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">方
法论的艺术管理，被称为科学和艺术的融合体，而管理的艺术性部分很大程度的体现为人的管理上。我说，方法学，一样是科学和艺术的融合体。这是有依据的，其
实方法论和管理学是近亲关系，管理学中有一门分支是项目管理，而在软件组织中，项目管理是非常重要的，方法学就是一种针对软件开发的一种特定的项目管理
（或是项目管理的一个子集）。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">重
型方法最大的一个问题就在于他不清楚或忽略了艺术这个层次，忽视了人的因素，把人做为一个计量单位，一种资源，一种线性元素。而人的要素在软件开发中是非
常重要的，软件开发实际上是一种知识、智力的转移过程，最终形成的产品是一种知识产品，它的成本取决于开发者的知识价值，因此，人是最重要的因素。而人这
个要素是很难衡量的，每个人都有不同的个性、想法、经验、经历，这么多复杂的因素加在一起，就导致了人的不可预见性。因此，我们强调管人的艺术。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">最
简单的例子是，在重型方法中，我们的基本假设是对人的不信任。项目经理要控制项目。但不信任就会产生很多的问题，比如士气不高，计划赶不上变化，创新能力
低下，跳槽率升高等等。人都是希望被尊重的，技术人员更看重这一点，而很多公司也口口声声说自己多么多么以人为本，可是采用的却是以不信任人为前提的开发
方法，言行不一。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我
们说敏捷方法的出发点是相互信任，做到这一点是很难的，但是一旦做到了，那这个团队就是非常具有竞争力的。因此，这就产生了一个问题，在没有做到完全的相
互信任之前，我们到底相不相信他人呢，这就是我提到的艺术性的问题，什么时候你要相信人？什么时候你不相信人，这些都是需要权衡的问题，也都是表现你艺术
性的问题。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">敏捷敏捷代表着有效和灵活。我们称那些轻型的、有效的方法为敏捷方法。在重型方法中，我们在一些不必要、重复的中间环节上浪费了太多的精力，而敏捷则避免了这种浪费。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我们的文章将会重点的讨论敏捷（Agile）方法论的思想，敏捷这个名字的前身就是轻型。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">目前已经有了一个敏捷联盟，他们制定了敏捷宣言： </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">Individuals
and interactions over processes and tools. Working software over
comprehensive documentation. Customer collaboration over contract
negotiation. Responding to change over following a plan. </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">而我对敏捷的理解包括了几个方面： </font></div>
<div><font size="3">&#183;
较低的管理成本和高质量的产出。软件开发存在两个极端：一个是没有任何的管理成本，所有的工作都是为了软件的产出，但是这种方式却往往导致软件开发过程的
混沌，产品的低质量，团队士气的低落。另一个是大量管理活动的加入，评审、变更管理，缺陷跟踪，虽然管理活动的加入能够在一定程度上提高开发过程的有序
性，但是成本却因此提高，更糟糕的是，很容易导致团队的低效率，降低创新能力。因此，敏捷方法视图寻找一个平衡点，用低成本的管理活动带来最大的产出，即
软件的高质量。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&#183; 尊重人性。敏捷方法尊重人性，强调效率。软件开发可以说是一种脑力的投入，如果不能保证开发人员的自愿投入，产品就肯定要打折扣。事实多次的证明，一个愿意投入的开发人员和一个不愿意投入的开发人员效率相差在三倍以上，对组织的贡献更是在十倍以上。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&#183; 沟通和反馈是一切的基础。我们已经讨论过沟通的重要程度，而即时的反馈是拥抱变化的前提条件。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&#183; 客户是上帝。没有客户就没有一切，客户的重要性可以用一句话来形容，就是以合理的成本建造合适的软件（build the right system at the right cost）。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">敏
捷其实也有轻重之分，关键在于是否能够做到有效和灵活。因此，敏捷方法论提倡的一个思想是"刚好够（barely
sufficient）"。不过这个"刚好够"可不是那么容易判断的。一支8个人的团队采用XP方法，随着方法的熟练使用，团队的能力在不断的增强，能够
处理的问题越越来越复杂，也许他们能够处理采用重型方法的20个人团队能够处理的问题。可是如果团队的人数突然增加到12人，这支团队肯定就会出问题，他
的表现可能还不如那支20个人的团队了。人数增加了的时候，原先的方法肯定还做适当的调整，比如说，在原先的敏捷方法上增加一些重型方法的技巧。我们不能
够要求一支6个人的团队和一支20个人的团队用同样的方法，前者可能采用轻一些的敏捷方法，后者可能采用重一些的敏捷方法，关键的问题在于，两支团队都把
重点放在沟通、反馈、频繁交付软件这些关键的因素上，也就是做到有效和灵活。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">架
构设计架构（Architecture）（也有被称为体系结构的）是软件设计中非常重要的一个环节。软件开发的过程中只要需求和架构确定之后，这个软件就
基本上可以定型了。这就好比骨骼确定了，这个人的体形就不会有很大的变化。因此我选择了架构设计来讨论敏捷软件开发（需求我已经写过了）。</font></div>
<div><font size="3">&nbsp; </font></div>
<div><font size="3">我
们在前面讨论过超集和子集的概念，因此我们接下去要讨论的架构设计也是一个很小的子集。方法论如果没有经历过多个项目的检验是不能称为成功的方法论的，我
也并不认为我的架构设计就是一个好的方法论，但引玉还需抛砖，他的主要目的是为了传播一种思想。因此，我采用了模式语言（PLOP）做为写作架构设计的形
式，主要的原因就是模式是一种很好的组织思想的方法。因此，在我们接下去的历程中，我们集中讨论的东西就围绕着架构、方法学、敏捷这三个要素展开。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">这篇文章并不是讨论如何编码实现软件架构的，也不要单纯的把它看作架构设计的指南，其实文中的很多思想来自于方法论，因此提到的很多架构设计的思想也适用于其它工作，如果能够了解这一点，看这篇文章的收获可能会更多一些。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">通过上一章的介绍，我们对敏捷和方法有了一个大致的了解，从这一章起，我们开始对软件开发过程中架构设计的研究。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">记住一点，我们并不是为了架构设计而研究架构设计，我们的目的在于敏捷方法学的应用。架构设计是一种权衡（trade-off）。一个问题总是有多种的解决方案。而我们要确定唯一的架构设计的解决方案，就意味着我们要在不同的矛盾体之间做出一个权衡。</font></div>
<div><font size="3">我们在设计的过程总是可以看到很多的矛盾体：开放和整合，一致性和特殊化，稳定性和延展性等等。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">任
何一对矛盾体都源于我们对软件的不同期望。可是，要满足我们希望软件稳定运行的要求，就必然会影响我们对软件易于扩展的期望。我们希望软件简单明了，却增
加了我们设计的复杂度。没有一个软件能够满足所有的要求，因为这些要求之间带有天生的互斥性。而我们评价架构设计的好坏的依据，就只能是根据不同要求的轻
重缓急，在其间做出权衡的合理性。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">目标我们希望一个好的架构能够： </font></div>
<div><font size="3">&#183;
重用：为了避免重复劳动，为了降低成本，我们希望能够重用之前的代码、之前的设计。重用是我们不断追求的目标之一，但事实上，做到这一点可没有那么容易。
在现实中，人们已经在架构重用上做了很多的工作，工作的成果称为框架（Framework），比如说Windows的窗口机制、J2EE平台等。但是在企
业商业建模方面，有效的框架还非常的少。 </font></div>
<div><font size="3">&#183; 透明：有些时候，我们为了提高效率，把实现的细节隐藏起来，仅把客户需求的接口呈现给客户。这样，具体的实现对客户来说就是透明的。一个具体的例子是我们使用JSP的tag技术来代替JSP的嵌入代码，因为我们的HTML界面人员更熟悉tag的方式。 </font></div>
<div><font size="3">&#183;
延展：我们对延展的渴求源于需求的易变。因此我们需要架构具有一定的延展性，以适应未来可能的变化。可是，如上所说，延展性和稳定性，延展性和简单性都是
矛盾的。因此我们需要权衡我们的投入/产出比。以设计出具有适当和延展性的架构。 &#183;
简明：一个复杂的架构不论是测试还是维护都是困难的。我们希望架构能够在满足目的的情况下尽可能的简单明了。但是简单明了的含义究竟是什么好像并没有一个
明确的定义。使用模式能够使设计变得简单，但这是建立在我熟悉设计模式的基础上。对于一个并不懂设计模式的人，他会认为这个架构很复杂。对于这种情况，我
只能对他说，去看看设计模式。 </font></div>
<div><font size="3">&#183;
高效：不论是什么系统，我们都希望架构是高效的。这一点对于一些特定的系统来说尤其重要。例如实时系统、高访问量的网站。这些值的是技术上的高效，有时候
我们指的高效是效益上的高效。例如，一个只有几十到一百访问量的信息系统，是不是有必要使用EJB技术，这就需要我们综合的评估效益了。 </font></div>
<div><font size="3">&#183; 安全：安全并不是我们文章讨论的重点，却是架构的一个很重要的方面。</font></div>
<div><font size="3">规则为了达到上述的目的，我们通常需要对架构设计制定一些简单的规则：功能分解顾名思义，就是把功能分解开来。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">为什么呢？我们之所以很难达到重用目标就是因为我们编写的程序经常处于一种好像是重复的功能，但又有轻微差别的状态中。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我
们很多时候就会经不住诱惑，用拷贝粘贴再做少量修改的方式完成一个功能。这种行为在XP中是坚决不被允许的。XP提倡"Once and only
once"，目的就是为了杜绝这种拷贝修改的现象。为了做到这一点，我们通常要把功能分解到细粒度。很多的设计思想都提倡小类，为的就是这个目的。所以，
我们的程序中的类和方法的数目就会大大增长，而每个类和方法的平均代码却会大大的下降。可是，我们怎么知道这个度应该要如何把握呢，关于这个疑问，并没有
明确的答案，要看个人的功力和具体的要求，但是一般来说，我们可以用一个简单的动词短语来命名类或方法的，那就会是比较好的分类方法。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我们使用功能分解的规则，有助于提高重用性，因为我们每个类和方法的精度都提高了。这是符合大自然的原则的，我们研究自然的主要的一个方向就是将物质分解。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我
们的思路同样可以应用在软件开发上。除了重用性，功能分解还能实现透明的目标，因为我们使用了功能分解的规则之后，每个类都有自己的单独功能，这样，我们
对一个类的研究就可以集中在这个类本身，而不用牵涉到过多的类。根据实际情况决定不同类间的耦合度虽然我们总是希望类间的耦合度比较低，但是我们必须客观
的评价耦合度。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">系统之间不可能总是松耦合的，那样肯定什么也做不了。而我们决定耦合的程度的依据何在呢？简单的说，就是根据需求的稳定性，来决定耦合的程度。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">对
于稳定性高的需求，不容易发生变化的需求，我们完全可以把各类设计成紧耦合的（我们虽然讨论类之间的耦合度，但其实功能块、模块、包之间的耦合度也是一样
的），因为这样可以提高效率，而且我们还可以使用一些更好的技术来提高效率或简化代码，例如Java中的内部类技术。可是，如果需求极有可能变化，我们就
需要充分的考虑类之间的耦合问题，我们可以想出各种各样的办法来降低耦合程度，但是归纳起来，不外乎增加抽象的层次来隔离不同的类，这个抽象层次可以是具
体的类，也可以是接口，或是一组的类（例如Beans）。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我
们可以借用Java中的一句话来概括降低耦合度的思想："针对接口编程，而不是针对实现编程。"
设计不同的耦合度有利于实现透明和延展。对于类的客户（调用者）来说，他不需要知道过多的细节（实现），他只关心他感兴趣的（接口）。这样，目标类对客户
来说就是一个黑盒子。如果接口是稳定的，那么，实现再怎么扩展，对客户来说也不会有很大的影响。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">以
前那种牵一发而动全身的问题完全可以缓解甚至避免。其实，我们仔细的观察GOF的23种设计模式，没有一种模式的思路不是从增加抽象层次入手来解决问题
的。同样，我们去观察Java源码的时候，我们也可以发现，Java源码中存在着大量的抽象层次，初看之下，它们什么都不干，但是它们对系统的设计起着重
大的作用。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">够用就好我们在上一章中就谈过敏捷方法很看重刚好够用的问题，现在我们结合架构设计来看：</font></div>
<div><font size="3">在
同样都能够满足需要的情况下，一项复杂的设计和一项简单的设计，哪一个更好。从敏捷的观点来看，一定是后者。因为目前的需求只有10项，而你的设计能够满
足100项的需求，只能说这是种浪费。你在设计时完全没有考虑成本问题，不考虑成本问题，你就是对开发组织的不负责，对客户的不负责。</font></div>
<div><font size="3">应
用模式这篇文章的写作思路很多来源于对模式的研究。因此，文章中到处都可以看到模式思想的影子。模式是一种整理、传播思想的非常优秀的途径，我们可以通过
模式的方式学习他人的经验。一个好的模式代表了某个问题研究的成果，因此我们把模式应用在架构设计上，能够大大增强架构的稳定性。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">抽
象架构的本质在于其抽象性。它包括两个方面的抽象：业务抽象和技术抽象。架构是现实世界的一个模型，所以我们首先需要对现实世界有一个很深的了解，然后我
们还要能够熟练的应用技术来实现现实世界到模型的映射。因此，我们在对业务或技术理解不够深入的情况下，就很难设计出好的架构。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">当然，这时候我们发现一个问题：怎样才能算是理解足够深入呢。我认为这没有一个绝对的准则。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">一次，一位朋友问我：他现在做的系统有很大的变化，原先设计的工作流架构不能满足现在的要求。他很希望能够设计出足够好的工作流架构，以适应不同的变化。但是他发现这样做无异于重新开发一个lotus notes。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我听了他的疑问之后觉得有两点问题：</font></div>
<div><font size="3">首先，他的开发团队中并没有工作流领域的专家。他的客户虽然了解自己的工作流程，但是缺乏足够的理论知识把工作流提到抽象的地步。显然，他本身虽然有技术方面的才能，但就工作流业务本身，他也没有足够的经验。所以，设计出象notes那样的系统的前提条件并不存在。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">其次，开发一个工作流系统的目的是什么。原先的工作流系统运作的不好，其原因是有变化发生。因此才有改进工作流系统的动机出现。</font></div>
<div><font size="3">可是，毕竟notes是为了满足世界上所有的工作流系统而开发的，他目前的应用肯定达不到这个层次。因此，虽然做不到最优的业务抽象，但是我们完全可以在特定目的下，特定范围内做到最优的业务抽象。比如说，我们工作流可能的变化是工组流路径的变化。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我们就完全可以把工作流的路径做一个抽象，设计一个可以动态改变路径的工作流架构。有些时候，我们虽然在技术上和业务上都有所欠缺，没有办法设计出好的架构。但是我们完全可以借鉴他人的经验，看看类似的问题别人是如何解决的。这就是我们前面提到的模式。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我们不要把模式看成是一个硬性的解决方法，它只是一种解决问题的思路。Martin Fowler曾说："模式和业务组件的区别就在于模式会引发你的思考。" </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">在《分析模式》一书中，Martin Fowler提到了分析和设计的区别。分析并不仅仅只是用用例列出所有的需求，分析还应该深入到表面需求的的背后，以得到关于问题本质的Mental Model。然后，他引出了概念模型的概念。概念模型就类似于我们在讨论的抽象。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">Martin Fowler提到了一个有趣的例子，如果要开发一套软件来模拟桌球游戏，那么，用用例来描述各种的需求，可能会导致大量的运动轨迹的出现。如果你没有了解表面现象之后隐藏的运动定律的本质，你可能永远无法开发出这样一个系统。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">关于架构和抽象的问题，在后面的文章中有一个测量模式的案例可以很形象的说明这个问题。架构的一些误解我们花了一些篇幅来介绍架构的一些知识。现在回到我们的另一个主题上来。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">对于一个敏捷开发过程，架构意味着什么，我们该如何面对架构。这里我们首先要澄清一些误解：</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&nbsp;&#183; 误解1：架构设计需要很强的技术能力。从某种程度来说，这句话并没有很大的错误。毕竟，你的能力越强，设计出优秀架构的几率也会上升。但是能力和架构设计之间并没有一个很强的联系。即使是普通的编程人员，他一样有能力设计出能实现目标的架构。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&nbsp;&#183;
误解2：架构由专门的设计师来设计，设计出的蓝图交由程序员来实现。我们之所以会认为架构是设计师的工作，是因为我们喜欢把软件开发和建筑工程做类比。但
是，这两者实际上是有着很大的区别的。关键之处在于，建筑设计已经有很长的历史，已经发展出完善的理论，可以通过某些理论（如力学原理）来验证设计蓝图。
可是，对软件开发而言，验证架构设计的正确性，只能够通过写代码来验证。因此，很多看似完美的架构，往往在实现时会出现问题。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&nbsp;&#183;
误解3：在一开始就要设计出完善的架构。这种方式是最传统的前期设计方式。这也是为XP所摒弃的一种设计方式。主要的原因是，在一开始设计出完美的架构根
本就是在自欺欺人。因为这样做的基本假设就是需求的不变性。但需求是没有不变的（关于需求的细节讨论，请参看拙作『需求的实践』）。这样做的坏处是，我们
一开始就限制了整个的软件的形状。而到实现时，我们虽然发现原来的设计有失误之处，但却不愿意面对现实。这使得软件畸形的生长。原本一些简单的问题，却因
为别扭的架构，变得非常的复杂。这种例子我们经常可以看到，例如为兼容前个版本而导致的软件复杂性。而2000年问题，TCP/IP网络的安全性问题也从
一个侧面反映了这个问题的严重性。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&#183; 误解4：架构蓝图交给程序员之后，架构设计师的任务就完成了。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">和
误解2一样，我们借鉴了建筑工程的经验。我们看到建筑设计师把设计好的蓝图交给施工人员，施工人员就会按照图纸建造出和图纸一模一样的大厦。于是，我们也
企图在软件开发中使用这种模式。这是非常要命的。软件开发中缺乏一种通用的语言，能够充分的消除设计师和程序员的沟通隔阂。有人说，UML不可以吗？
UML的设计理念是好的，可以减轻沟通障碍问题。可是要想完全解决这个问题，UML还做不到。</font></div>
<div><font size="3">首先，程序员都具有个性化的思维，他会以自己的思维方式去理解设计，因为从设计到实现并不是一项机械的劳动，还是属于一项知识性的劳动（这和施工人员的工作是不同的）。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">此
外，对于程序员来说，他还极有可能按照自己的想法对设计图进行一定的修改，这是非常正常的一项举动。更糟的是，程序员往往都比较自负，他们会潜意识的排斥
那些未经过自己认同的设计。架构设计的过程模式通常我们认为模式都是用在软件开发、架构设计上的。其实，这只是模式的一个方面。模式的定义告诉我们，模式
描述了一个特定环境的解决方法，这个特定环境往往重复出现，制定出一个较好的解决方法有利于我们在未来能有效的解决类似的问题。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">其
实，在管理学上，也存在这种类似的这种思维。称为结构性问题的程序化解决方法。所以呢，我们完全可以把模式的思想用在其它的方面，而目前最佳的运用就是过
程模式和组织模式。在我们的文章中，我们仅限于讨论过程模式。我们讨论的过程仅限于面向对象的软件开发过程。我们称之为OOSP（object-
oriented software process
）。因为我们的过程需要面向对象特性的支持。当然，我们的很多做法一样可以用在非OO的开发过程中，但是为了达到最佳的效果，我建议您使用OO技术。那
么，我们应该如何避开这些误区呢，或者，换句话说，敏捷软件开发是如何做架构设计的。</font></div>
<div><font size="3">这
里有几种过程模式：图 2.
敏捷架构过程模式概览（High-Level）在接下去的篇幅中，我们会逐一对各种过程模式进行介绍。然后再站在全局的角度分析各个模式之间的关系，并将
之归纳为架构设计的模式。敏捷型架构设计我们说我们这里列出的过程模式是敏捷型的，关于这一点我们会在接下去的各个章节中验证这一点。我们列出的各个过程
模式并不是完全照搬敏捷型方法，因为在各种敏捷型方法中，某些技巧适合架构设计，某些方法则不适合架构设计。因此，我们在采用一种方法和技术前，我们会问
自己几个简单的问题：该方法/技巧有什么价值？ 该方法/技巧需要多大的投入？从创建、维护、培训等多方面估计。
比较该方法/技巧的投入和价值，它还值得我们采用吗？ 是否还有其它价值/投入比更高的方法/技巧呢？</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">在
我们的文章中，每一种方法/技巧的讨论都回答了前三个问题，至于第四个问题，希望有同行能够告诉我。
我们说，和重型方法偏重于计划、过程和中间产物不同，敏捷方法更加看重人和沟通。人和沟通永远是第一位的，而计划、过程和中间产物，那只是保证沟通、实现
目标的手段。这并不是说计划、过程、中间产物不重要，只是不能够本末倒置注：我们把中间产物定义为为了实现跨边界的沟通而制定的文档、模型、代码。例如设
计文档、数据模型等。参考RUP的Artifact。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">评
判软件成功的标准有很多，对于敏捷方法论来说，成功的标准首先在于交付可用的软件。为了保证软件的可用性，最重要的就是做好需求。做好需求的方法有很多
（参见拙作需求的实践），但这并不是我们讨论的主题。对于我们要开始的架构设计的工作来说，从需求出发来设计架构，这就是保证软件可用性的一个基本的保
证。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&nbsp;Context </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我
们如何开始我们的架构设计工作？ Problem
我们在进行架构设计的时候，往往主要考虑的都是平台、语言、开发环境、数据库等一些基本问题，可是对于和客户的具体情况密切相关的一些问题却很少系统的考
虑。甚至还存在一种误区，认为架构设计无非就是写一些空话，套话。这样子做出来架构设计，如何用于指导软件的实现呢？
IT界的技术层出不穷，面对着如此之多的技术、平台、框架、函数库，我们如何选择一组适合软件的技术？每一个客户的软件都有自身的特点，如何才能够设计出
符合客户利益的架构？软件中往往都充斥着众多的问题，在一开始就把所有的问题都想清楚往往很难做到，但是如果不解决问题，风险又居高不下。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">Solution </font></div>
<div><font size="3">&nbsp; </font></div>
<div><font size="3">针
对需求设计架构。架构设计就是铺设软件的主管道（例1）。我们根据什么来制定主管道的粗细、路径等因素呢？很明显，是根据城市的人口、地理位置、水源等因
素来决定的。对应到软件设计也是一样的。城市的各因素就是软件中的各种需求：功能需求、非功能需求、变化案例等等。一般来说，功能需求决定业务架构、非功
能需求决定技术架构，变化案例决定架构的范围。需求方面的知识告诉我们，功能需求定义了软件能够做些什么。我们需要根据业务上的需求来设计业务架构，以使
得未来的软件能够满足客户的需要。非功能需求定义了一些性能、效率上的一些约束、规则。而我们的技术架构要能够满足这些约束和规则。变化案例是对未来可能
发生的变化的一个估计，结合功能需求和非功能需求，我们就可以确定一个需求的范围，进而确定一个架构的范围。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">从
例2中，我们看到自已字处理软件的几种需求的范例。真正的字处理软件要复杂的多。而我们最主要的就是必须认识到，架构是来自于需求的。有什么样的需求就有
什么样的架构。试想一下，如果我们没有对速度的要求，我们还需要考虑这方面的设计吗？我们上面提到了几种类型的需求对架构的影响，其实还有一个很重要的需
求，就是环境的需求。这并不是一个很重要的需求，但是对于部署（deployment）架构设计来说就特别重要。毕竟，我们开发出的软件是要上"战场"
的，充分的考虑部署问题是非常有必要的。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">例1：
城市中自来水管的架设是一项非常的复杂的工程。为了需要满足每家每户的需要，自来水管组成了一个庞大的网络。在这样一个复杂的网络中，如何完成铺设的任务
呢。一般的做法是，先找出问题的根源，也就是水的源头。从水源铺设一条管道通至城市，然后根据城市的区域划分，设计出主管道，剩下的就是使用的问题了，每
家每户的管道最终都是连到主管道上的。因此，虽然自来水网络庞大复杂。但是真正的主管道的非常简单的。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">例2：
我们打算开发一个字处理软件，功能需求可以简单概括为格式化用户输入的文字，非功能需求可能是格式化大小为1000K的一段文字的处理速度不能低于
10S，变化案例可能是推出多种语言版本。那么我们在设计业务架构的时候，我们会集中于如何表示文字、图象、媒体等要素，我们该需要有另外的技术架构来处
理速度问题，比如缓冲技术，对于变化案例，我们也要考虑相应的架构，比如把字体独立于程序包的设计。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">从需求到架构。在需求阶段，我们可以得到一些代表需求调研成果的中间产物。比如说，CRC卡片、基本用例模型、用户素材、界面原型、界面原型流程图、非功能需求、变化案例等。我们在架构设计阶段的主要工作就是要把这些需求阶段的中间产物转换为架构设计阶段的中间产物。</font></div>
<div><font size="3">图 3.</font><font size="3">&nbsp;
需求阶段的中间产物
其实，架构设计就是要完成两项工作，一是分析，二是设计。分析是分析需求，设计则是设计软件的大致结构。很多的方法论把分析和设计两种活动分开来，但其实
这两者是很难区分的，做分析的时候会想到如何设计，而思考如何设计反过来又会影响分析的效果。可以说，他们两者之间是相互联系和不断迭代的。这种形态我们
将会在后面的迭代设计模式中详细的讨论。在敏捷方法论中，需求最好是迭代进行的，也就是说一点一点的作需求。这种做法在那些需求变化快的项目中尤其适用。
由于我们采用的流程是一种迭代式的流程，这里我们将会面临着如何对待上一次迭代的中间产物的问题。如果我们每一次迭代都需要修改已存在的中间产物，那么这
种维护的成本未免过大。因此，敏捷方法论的基本做法是，扔掉那些已经没有用处的中间产物。还记得在第一章的时候，我们强调说软件要比文档重要。我们生成中
间产物的目的都是为了生成最终的程序，对于这些已经完成作用的模型，没有必要付出额外的维护成本。不要断章取义的采用抛弃模型的做法。因为，抛弃模型的做
法需要一个适合环境的支持。后面会针对这个话题开展大范围的讨论。这里我们简单的做一个了解：</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&nbsp;&#183; 简单化：简单的模型和简单的程序。模型和程序越复杂，就需要更多的精力来处理它们。因此，我们尽可能的简化它们，为的是更容易的处理它们。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&#183; 高效的沟通渠道：通过增强沟通的效果来减少对中间产物的需要。试想一下，如果我随时能够从客户那里得到需求的细节资料，那前期的需求调研就没有必要做的太细致。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&#183; 角色的交叉轮换：开发人员之间建立起交换角色的机制，这样，能够尽量的避免各子系统诸侯割据的局面。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&#183; 清晰的流程：或者我们可以称之为明确的过程。过程在方法论中向来都是一个重点，敏捷方法论也不例外。开发人员能够清楚的知道，今天做什么，明天做什么。过程不是给别人看的，而是给自己用的。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&#183; 工具：好用的工具能够节省大量的时间，这里的工具并不仅仅指CASE工具，还包括了版本控制工具、自动化测试工具、画图工具、文档制作和管理工具。使用工具要注意成本和效益的问题。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">&#183; 标准和风格：语言不通是沟通的一个很大的障碍。语言从某个角度来看属于一种标准、一种风格。因此，一个团队如果采用同样的编码标准、文档标准、注释风格、制图风格，那么这个团队的沟通效率一定非常的高。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">如
果上述的环境你都不具备，或是欠缺好几项，那你的文档的模型还是留着的好。仅针对需求设计架构仅针对需求设计架构的含义就是说不要做未来才有用的事情。有
时候，我们会把架构考虑的非常复杂，主要的原因就是我们把很多未来的因素放入到现在来考虑。或者，我们在开发第一个产品的时候就视图把它做成一个完美的框
架。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">以上的
这两种思路有没有错呢？没有错，这只是如何看待投入的问题，有人希望开始的时候多投入一些，这样后续的投入就会节省下来。但在现实中，由于需求的不确定
性，希望通过增加开始阶段的投入来将降低未来的投入往往是难以做到的，框架的设计也绝对不是能够一蹴而就的，此这种做法并不是一个好的做法。所以我们在后
头会着重论述架构设计的简单性和迭代过程，也就是因为这个理由。模式模式将可以帮助我们抓住重点。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">设
计模式在书的一开始（第二章）就讨论了一个设计一个文档编辑器的问题。为了解决设计文档编辑器引出的七个问题，一共使用了8种不同的模式。这8种模式的组
合其实就是架构，因为它们解决的，都是系统中最高层的问题。在实践中，人们发现架构也是存在模式的。比如，对于系统结构设计，我们使用层模式；对于分布式
系统，我们使用代理模式；对于交互系统，我们使用MVC（模型-视图-控制器）模式。模式本来就是针对特定问题的解，因此，针对需求的特点，我们也可以采
用相应的模式来设计架构。在sun网站上提供的宠物商店的范例中，就把MVC模式的思想扩展成为架构的思想，用于提供不同的界面视图：
MVC架构图，这里提供原图的概览，查看其出处请点击这里。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我
们可以了解到在图的背后隐藏着的需求：系统需要支持多种用户界面，包括为普通用户提供的HTML界面，为无线用户提供的WML界面，为管理员提供的
Swing界面，以及为B2B业务设计的WebService界面。这是系统最重要的需求，因此，系统的设计者就需要确定一个稳定的架构，以解决多界面的
问题。相对于多界面的问题，后端的业务处理逻辑都是一致的。比如HTML界面和WML界面的功能并没有太大的差别。把处理逻辑和界面分离开来还有额外的好
处，可以在添加功能的同时，不涉及界面的改动，反之亦然。这就是我们在第二篇中提到的耦合度的问题。
MVC模式正可以适用于解决该问题。系统使用控制器来为业务逻辑选择不同的界面，这就完成了MVC架构的设计思路。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">在架构设计的工作中，我们手头上有模式这样一张好牌，有什么理由不去使用它呢？抓住重点在架构设计一开始，我们就说架构是一种抽象，那就是说，架构设计摒弃了具体的细节，仅仅抓住软件最高层的概念，也就是最上层、优先级最高、风险最大的那部分需求。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">我
们考虑、分析、解决一个问题，一定有一个渐进的过程。架构设计就是解决问题其中比较早期的一个阶段，我们不会在架构设计这个阶段投入过多的时间（具体的原
因在下文会有讨论），因此关键点在于我们要能够在架构设计中把握住需求的重点。比如，我们在模式一节中提到了分布式系统和交互系统，分布和交互就是这两个
系统的重点。那么，如果说我们面对的是一个分布式的交互系统，那么，我们就需要把这两种特性做为重点来考虑，并以此为基础，设计架构。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">而
我们提到的宠物商店的范例也是类似的，除了MVC的架构，还有很多的设计问题需要解决，例如用于数据库访问的数据对象，用于视图管理的前端控制器，等等
（具体使用到的架构模式可以访问sun的网站）。但是这些相对于MVC模式来说，属于局部的，优先级较低的部分，可以在架构确定后再来设计。架构设计和领
域专家一个架构要设计的好，和对需求的理解是分不开的。因此在现实中，我们发现业务领域专家凭借着他对业务领域的了解，能够帮助开发人员设计出优秀的架构
来。架构是需要抽象的，它是现实社会活动的一个基本模型，而业务领域的模型仅仅凭开发人员是很难设计出来的。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">在ERP的发展史上，我们看到MRP发展为MRPII，在发展到闭环MRP，直到发展成为现在的ERP，主要的因素是管理思想的演化，也就是说，对业务领域的理解进步了，架构才有可能进步。因此，敏捷型架构设计的过程中，我们也非常强调领域专家的作用。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">例3：
信贷系统在一个银行的信贷帐务处理系统中，我们应该如何把握最初的架构思路呢？从需求上来看，这个信贷帐务处理系统有几个特点：它不是一个单独的系统，它
需要和外部的其它系统交互，例如信贷业务系统、网上银行、数据仓库系统等。在所有的需求中，最复杂的就是它的利息计算的需求，它要求能够支持多种的利息算
法。因此，我们的架构设计首先是从系统的全局环境开始考虑。其它系统和该系统的关系如何，应该如何设计系统间的接口。通过需求的调研，系统的接口分为4
类：和企业外部系统的接口。信贷系统需要连接到人民银行的系统。和企业内部系统的接口。信贷系统需要能够为数据仓库系统和网上银行系统提供数据。和平级系
统的接口。信贷系统需要从平级的帐户、资金、财务系统中取数据，并向帐户、押汇系统发送数据。</font></div>
<div><font size="3">具
体的实现策略并不在我们的讨论范围之内，但是可以看到，架构策略的制定是以需求为基础的。我们可以把这部分的需求归纳为技术架构或平台架构。然后是利息算
法的问题，我们经过统计，目前的利息计算方式有四种，可预见到的还有两种。在一开始的阶段，我们并不需要考虑具体算法的实现，但是我们需要考虑算法的实现
框架，因此我们很自然的想到Strategy模式可以胜任这一工作，把不同的利息算法封装起来。而我们的工作重点也就转到定义利息算法的接口问题。通过分
析、比较多种利息算法，我们定义了一个最初始的算法接口，然后由不同的利息算法来实现算法接口。虽然，这个接口目前还不是很完整，但是它会在接下去的开发
过程中慢慢的完善起来。这部分的需求属于业务架构的一部分。考虑到系统的结构非常的复杂，因此在系统结构的处理上，我们采用了层模式做为系统的基本结构。
此外，在每个层，我们还定义了几个子模块来处理特定的问题。这样，我们就可以将复杂的功能有序的组织起来。经过上述的分析，我们对系统的架构有了一个简单
的认识，但是还没有结束，一个架构应该包括系统的各个基本部分，因此，我们还要考虑票据处理、报表、帐务处理等环节，但是一开始就考虑周详，这要花费大量
的时间，因此我们只是简单的定义了一个原始的架构，然后在后续的开发过程中把这个架构完善起来。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">团
队设计是敏捷方法论中很重要的一项实践。我们这里说的团队，指的并不是复数的人。一群人就是一群人，并没有办法构成团队。要想成为团队，有很多的工作要
做。
我们之所以考虑以团队为单位来考虑架构设计，是因为软件开发本身就不是一件个人的事情，架构设计更是如此。单个人的思维不免有考虑欠妥之处，单个人的学识
也不可能覆盖所有的学科。而组织有效的团队却能够弥补这些缺憾。 </font></div>
<div><font size="3">Context </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">谁来负责架构的设计？ </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">Problem </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">在我们的印象中，总认为架构设计是那些所谓架构设计师的专属工作，他们往往拥有丰富的设计经验和相关的技能，他们不用编写代码，就能够设计出理论上尽善尽美的架构，配有精美的图例。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">问题1：理论上设计近乎完美的架构缺乏程序的证明，在实际应用中往往会出这样那样的问题。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">问题2：设计师设计架构带有很大的主观性，往往会忽视客户的需求，导致架构无法满足需求。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">问题3：实现的程序员对这种架构有抵触的情绪，或是因为不理解架构而导致架构实现的失败。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">问题4：架构师设计架构主要是依据自己的大量经验，设计出的架构不能真实的反映目前的软件需要。 </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">Solution </font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">团
队设计的理论依据是群体决策。和个人决策相比，群体决策的最大好处就是其结论要更加的完整。而群体决策虽然有其优点，但其缺点也是很明显的：需要额外付出
沟通成本、决策效率低、责任不明确、等等。但是群体决策如果能够组织得当的话，是能够在架构设计中发挥很大的优势的。避免象牙塔式的架构设计对软件来说，
架构设计是一项至关重要的工作。这样的工作交给某个人是非常危险的。即便这个人再怎么聪明，他也可能会遗漏部分的细节。组织有效的团队的力量是大大超过个
人的力量的，因此团队的成果较之个人的成果，在稳定性和思考的周密程度上，都要更胜一筹。 Scott W.
Ambler在其著作中给出了象牙塔式架构（ivory tower architecture）的概念： An ivory tower
architecture is one that is often developed by an architect or
architectural team in relative isolation to the day-to-day development
activities of your project team(s).
中国现在的软件开发行业中也逐渐出现了象牙塔式的架构设计师。这些架构师并不参与实际的程序编写，他的工作就是为项目制作出精美的架构模型，这种架构模型
在理论上是相当完美的。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">例1：
在XP中，我们基本上看不到架构设计的影子。并不是说采用XP技术的团队就不需要架构设计。XP不存在专门的设计时期，它提倡使用一些简单的图例、比喻的
方式来表达软件的架构，而这种的架构设计是无时无刻不在进行的。其实，XP中的设计采用的就是团队设计的方式，结队编程（Pair
Programming）和代码的集体所有制（Collective
Ownership）是团队设计的基础，也就是基于口述的沟通方式。通过采用这样的方式，XP几乎不需要文档来表达架构的设计。
优秀的架构师能够充分的利用现有框架，减少软件的投入，增强软件的稳定性。这些都没有错，但是问题在于&#8220;过犹不及&#8221;。象牙塔式架构师往往会出现文章开始指
出的那些问题。架构设计其实并不是非常复杂的工作，但它要求开发人员具备相关的技能、经验以及对问题域有一定的了解。开发人员往往都具有相关的技术技能
（编程、数据库设计、建模），而对问题域的理解可以从用户和行业专家那里获得帮助。因此，在理论上，我们要实现架构设计的团队化是完全可能的。在上面的象
牙塔式架构定义中，我们看到架构师和日常的开发工作是隔绝的。这样的设计出的架构有很大的局限性。在现实中，我们还会发现另外一种角色，他来自于开发团队
外部，为开发人员提供相关的技术或业务的培训。这种角色称为教练，在软件开发中是非常重要的角色，不能够和象牙塔式架构设计师之间画等号。选择你的设计团
队。
软件的架构在软件的生命周期的全过程中都很重要，也就是说，软件开发团队中的所有人员都需要和架构打交道。因此，最好的团队组织方式是所有开发人员都参与
架构的设计，我们称这种方式为全员参与。全员参与的方式保证了所有开发人员都能够对架构设计提出自己的见解，综合多方面的意见，在全体开发人员中达成一
致。这种方式尤其适合于一些小的团队。还是会有很多的团队由于种种的原因不适合采用全员参与的方式。那么，组织优秀的开发人员组成设计组也是比较好的方
式。一般，我们选择那些在项目中比较重要的，有较多开发经验，或是理论扎实的那些人来组成设计组。当然，如果你考虑到为组织培养后续力量，你也可以让一些
新手加入设计组，或是你觉得自己的开发力量不足，邀请外部的咨询力量介入，这完全取决于具体的情况。
设计组不同于我们之前提到的象牙塔式架构设计师。设计组设计出来的架构只能称为原始架构，它是需要不断的反馈和改进的。因此，在架构实现中，设计组的成员
将会分布到开发团队的各个领域，把架构的思想带给所有开发人员，编写代码来检验架构，并获得具体的反馈，然后所有的成员再集中到设计组中讨论架构的演进。
团队设计中存在的问题在团队设计的过程，我们会遇到各种各样的问题，首当其冲的就是沟通成本的问题。架构设计时，需求尚未被充分理解，软件的设计思路还处
于萌发的状态。这样的情况下，团队的每位成员对软件都有独特的见解，这些可能有些是相同的，有些是互斥的。就好比盲人摸象一样，他们的观点都代表了软件的
一部分或是一方面，但是没有办法代表软件的全部。在敏捷方法论中，我们的每一个流程都是迅速进行、不断改进的。架构设计也是一样，我们不可能在一次架构设
计上花费更多的时间。而团队决策总是倾向于较长的讨论和权衡。例2中的问题在架构设计中时有发生，纯技术的讨论很容易上升称为争吵。这种情况几乎没有办法
完全避免。团队型的决策必然会发生观念的冲突。控制一定程度内的观念的冲突对团队的决策是有益，但是如果超出了这个程度就意味着失控了，需要团队领导者的
调节。而更重要的，我们需要注意沟通的技巧：团队沟通团队进行架构设计的时候沟通是一个非常需要注意的问题，上述的情境在软件组织中是经常发生的，因为技
术人员很自然认为自己的技术比别人的好，如果自己的技术受到质疑，那怕对方是抱着讨论的态度，也无异于自身的权威受到了挑战，面子是无论如何都需要捍卫
的。而沟通如果带上了这样一层主观色彩，那么沟通信息的受众就会潜意识的拒绝接受信息。相反，他会找出对方话语中的漏洞，准备进行反击。因此，我们要注意
培养一种良好的沟通氛围。在实际的观察中，我发现团队沟通中存在两种角色，一种是建议者，他们经常能够提出建议。一种是质疑者，他们对建议提出否定性的看
法。这两种角色是可能互换的，现在的建议者可能就是刚才的质疑者。质疑者的发言是很能打击建议者的积极性的，而在一个脑力激荡的会议中，最好是大家都能够
扮演建议者的角色，这就要求沟通会议的主持者能够掌握好这一点，对建议给予肯定的评价，并鼓励大家提出新的建议。例2：敏捷方法非常注重的就是团队的沟
通。沟通是一个很有意思的话题，讲起来会花费大量的时间，我们这里只是针对架构设计中可能存在的沟通问题做一个简单的讨论。我们这里假设一个讨论情境，这
个情境来源于真实的生活：项目主管徐辉、设计师李浩、设计师罗亦明正在讨论一个新的软件架构。
"李浩你认为这个软件数据库连接部分应该如何考虑？"徐辉问。李浩想了想，"我觉得方案A不错&#8230;"
"方案A肯定有问题！这个软件和上一次的又不同。"罗亦明打断了李浩的发言。
"你懂什么！你到公司才多久，方案A是经过很长时间的证明的！"发言被打断，李浩有点恼火，罗亦明进入公司没有多久，但在一些事情上老是和他唱反调。
"我进公司多久和方案A的错误有什么关系！" 在这样一种氛围中，会议的结果可想而知。
良好的沟通有助于架构设计工作的开展。一个成员的能力平平的团队，可以藉由良好的沟通，设计出优秀的架构，而一个拥有一个优秀成员的团队，如果缺乏沟通，
最后可能连设计都出不来。这种例子现实中可以找到很多。标准和风格
我们总是在不知不觉之中使用各种各样的标准和风格。在团队设计中，我们为了提高决策的效率，可以考虑使用统一的标准和风格。统一的标准和风格并不是一朝一
夕形成的。因为每个人都有自己不同的习惯和经历，强制性的要求开发人员使用统一的标准（风格）容易引起开发人员的不满。因此在操作上需要注意技巧。对架构
设计而言，比较重要的标准（风格）包括以下的这些类别：界面设计 流程设计 建模规范 编码规范 持久层设计 测试数据
在我的经验中，有一些组织平时并不注意标准（风格）的积累，认为这种积累属于雕虫小技，但正是这些小技，能够非常有效的提高沟通的效率和降低开发人员的学
习曲线。试想一下，如果一个团队中所有人写出的代码都是不同标准和风格的，那么理解起来肯定会困难许多。当然，我们没有必要自己开发一套标准（风格）出
来，现实中有很多可以直接借用的资料。最好的标准是UML语言，我们可以从UML的官方网站下载到最新的规范，常用的编码标准更是随处可见。不过虽然有了
统一的标准，如果风格不统一，同样会造成沟通的障碍。例如下图显示的类图，虽然它们表示的是同一个类，但是由于版型、可视性、详细程度的差别，看起来又很
大的差别。而在其它的标准中，这种差别也是普遍存在的。因此，我们在使用了统一的标准之后，还应该使用同样的风格。Scott W.
Ambler专门成立了一个网站讨论UML的建模风格的相关问题，有兴趣的读者可以做额外的阅读。图 4. 两种风格的类图
在统一的风格的基础上更进一步的是使用术语。使用沟通双方都了解专门的术语，可以代表大量的信息。最好的术语的范例就是设计模式的模式名。如果沟通的双方
都了解设计模式，那么一方只需要说这部分的设计可以使用工厂模式，另一方就能够理解，而不用再详细的解释设计的思路。这种的沟通方式是最高效的，但它所需
要的学习曲线也会比较陡。团队设计的四明确为了最大程度的提高团队设计的高效性，可以从4个方面来考虑： 1、明确目标
泛泛的召开架构讨论会议是没有什么意义的，一个没有鲜明主题的会议也不会有什么结果。在源自需求的模式中，我们谈到说可以有非功能需求的架构，可以有功能
需求的架构。因此，在进行团队设计之前，我们首先也需要确定，此次要解决什么问题，是讨论业务逻辑的架构，还是技术架构；是全局性的架构，还是各模块的架
构。 2、明确分工
我们之所以重视团队，很重要的额一个原因就是不同的成员有不同的擅长的区域。有些成员可能擅长于业务逻辑的建模，有的擅长于原型设计，有的擅长于数据库设
计，有的则擅长于Web编程。你能够想象一个软件没有界面吗？（有些软件可能是这种情况）你能够想象一个软件只有数据库，而没有处理逻辑吗？因此，架构设
计就需要综合的考虑各个方面，充分利用成员的优势。这就要求团队的各个成员都能够明确自己的分工。
3、明确责权除了明确自己的分工，每位成员都需要清楚自己的责任。没有责任，分工就不会有任何的效力。每位成员都需要明确自己要做些什么。当然，和责任相
对的，没有成员还需要知道自己的权力是什么。这些清楚了，进行高效的沟通的前提就具备了。每次架构的讨论下来，每个人都清楚，自己要做些什么，自己需要要
求其他人做些什么，自己该对谁负责。如果这些问题回答不了，那这次的讨论就白费了。
4、明确沟通方式这里使用沟通方式可能有一点点不恰当，为了明确的表达意思，大家可以考虑信息流这个词。一个完整架构包括几个方面，分别都由那些人负责，
如何产生，产生的整个过程应该是什么样的？这样的一个信息流程，囊括了上面提到的三个明确。如果团队的每一个人都能够为架构的产生而努力，并顺利的设计出
架构，那么这样的流程是完美的。如果你发现其中的一些人不知道做些什么，那么，这就是流程出问题的现象了。完美的流程还会有一个额外的副产品，架构产生之
后，团队对于软件的设计已经是非常的清晰了。因为我们提倡的是尽可能多的开发人员参与架构的设计。不仅仅是架构讨论到这里，其实有很多的内容已经脱离了架
构设计了。也就是说，很多的原则和技巧都是可以用于软件开发的其它活动的。至于哪一些活动能够利用这些方法呢？大家可以结合自己的实际情况，来思考这个问
题。提示一点，关键的入手处在于目前效率较低之处。
XP非常强调简单的设计原则：能够用数组实现的功能决不用链表。在其它Agile方法中，简单的原则也被反复的强调。在这一章，我们就对简单性做一个全面
的了解。 Context 架构应该设计到什么程度？ Problem
软件的架构都是非常的复杂的，带有大量的文档和图表。开发人员花在理解架构本身上的时间甚至超出了实现架构的时间。在前面的文章中，我们提到了一些反对象
牙塔式架构的一个原因，而其中的一个原因就是象牙塔式架构的设计者往往在设计时参杂进过多的自身经验，而不是严格的按照需求来进行设计。在软件开发领域，
最为常见的设计就是"Code and
Fix"方式的设计，设计随着软件开发过程而增长。或者，我们可以认为这种方式根本就不能算是设计，它抱着一种船到桥头自然直的态度，可是在设计不断改动
之后，代码变得臃肿且难以理解，到处充满着重复的代码。这样的情形下，架构的设计也就无从谈起，软件就像是在风雨中的破屋，濒临倒塌。针对于这种情形，新
的设计方式又出现了，Martin Fowler称这种方式为"Planned
Design"。和建筑的设计类似，它强调在编码之前进行严格的设计。这也就是我们在团队设计中谈到的架构设计师的典型做法。设计师们通常不会去编程，理
由是在土木工程中，你不可能看到一位设计师还要砌砖头。 "Planned Design"较之"Code and
Fix"进步了许多，但是还是会存在很多问题。除了在团队设计中我们谈的问题之外，需求变更将会导致更大的麻烦。因此，我们理所当然的想到进行"弹性设计
"：弹性的设计能够满足需求的变更。而弹性的设计所付出的代价就是复杂的设计。题外话：这里我们谈论"Planned
Design"引出的一些问题，并没有任何排斥这种方式的意思。"Planned
Design"还是有很多可取之处的，但也有很多需要改进的地方。事实上，本文中我们讨论的架构设计方式，本质上也是属于"Planned
Design"方式。和"Planned Design"相对应的方式是XP所主张的"Evolutionary
Design"方式，但是这种方式还有待于实践的检验，并不能简单的说他就一定要比"Planned
Design"先进或落后。但可以肯定的一点是："Evolutionary Design"方式中有很多的思想和技巧是值得"Planned
Design"借鉴的。 Solution XP中有两个非常响亮的口号："Do The Simplest Thing that Could
Possibly Work"和"You Aren't Going to Need
It"（通常称之为YAGNI）。他们的核心思想就是不要为了考虑将来，把目前并不需要的功能加到软件中来。粗看之下，会有很多开发人员认为这是不切实际
的口号。我能理解这种想法，其实，在我热衷于模式、可重用组件技术的时候，我对XP提倡的简单的口号嗤之以鼻。但在实际中，我的一些软件因为复杂设计导致
开发成本上升的时候，我重新思考这个问题，发现简单的设计是有道理的。降低开发的成本不论是模式，可重用组件，或是框架技术，目的都是为了降低开发的成
本。但是他们的方式是先进行大量的投入，然后再节省后续的开发成本。因此，架构设计方面的很多思路都是围绕着这种想法展开的，这可能也是导致开发人员普遍
认为架构设计高不可攀的原因。
XP的方式恰恰相反，在处理第一个问题的时候，不必要也不可能就设计出具有弹性、近乎完美的架构来。这项工作应该是随着开发的演进，慢慢成熟起来的。我不
敢说这种方式肯定正确，但是如果我们把生物的结构视同为架构，这种方式不是很类似于自然界中生物的进化方式吗？在一开始就制作出完美的架构的设想并没有
错，关键是很难做到这一点。总是会有很多的问题是你在做设计时没有考虑到的。这样，当一开始花费大量精力设计出的"完美无缺"的架构必然会遇到意想不到的
问题，这时候，复杂的架构反而会影响到设计的改进，导致开发成本的上升。这就好比如果方向错了，交通工具再快，反而导致错误的快速扩大。Martin
Fowler在他的论文中说，"Working on the wrong solution early is even more
wasteful than working on the right solution
early"（提前做一件错事要比提前做一件对的事更浪费时间），相信也是这个道理。更有意思的是，通常我们更有可能做错。在我们进行架构设计的时候，我
们不可能完全取得详细的需求。事实上，就算你已经取得了完整的需求，也有可能发生变化。这种情况下做出的架构设计是不可能不出错的。这样，浪费大量的时间
在初始阶段设计不可能达到的"完美架构"，倒不如把时间花在后续的改进上。提升沟通的效率我们在团队设计中已经谈过了团队设计的目标之一就是为了降低沟通
的成本，以期让所有人都能够理解架构。但是如果架构如果过于复杂，将会重新导致沟通成本的上升，而且，这个成本并不会随着项目进行而降低，反而会因为上面
我们提到的遇到新的问题导致沟通成本的持续上升。简单的架构设计可以加快开发团队理解架构的速度。我们可以通过两种方式来理解简单的含义。首先，简单意味
着问题的解不会非常的复杂，架构是解决需求的关键，无论需求再怎么复杂多变，总是可以找出简单稳定的部分，我们可以把这个简单稳定的部分做为基础，再根据
需要进行改进扩展，以解决复杂的问题。在示例中，我们提到了measurement
pattern，它就是按照这种想法来进行设计的。其次，简单性还体现在表示的简单上。一份5页的文档就能够表达清楚的架构设计为什么要花费50页呢？同
样的道理，能够用一副简单的图形就能够表示的架构设计也没有必要使用文档。毕竟，面对面的沟通才是最有效率的沟通，文档不论如何的复杂，都不能被完全理
解，而且，复杂的文档，维护起来也需要花费大量的时间。只有在两种情况下，我们提倡使用复杂的文档：一是开发团队没有办法做到面对面沟通；二是开发成果要
作为团队的知识积累起来，为下一次开发所用。考虑未来我们之所以考虑未来，主要的原因就是需求的不稳定。因此，我们如果考虑未来可能发生的需求变化，就会
不知觉的在架构设计中增加复杂的成分。这违背的简单的精神。但是，如果你不考虑可能出现的情况，那些和目前设计格格不入的改变，将会导致大量的返工。还记
得YAGNI吗？原则上，我们仍然坚持不要在现有的系统中为将来可能的情况进行设计。但是，我们必须思考，必须要为将来可能出现的情况做一些准备。其实，
软件中了不起的接口的思想，不就是源于此吗？因此，思考未来，但等到需要时再实现。变更案例有助于我们思考未来，变更案例就是你在将来可能要（或可能不
要）满足的，但现在不需要满足的需求。当我们在做架构设计的时候，变更案例也将会成为设计的考虑因素之一，但它不可能成为进行决策的唯一考虑因素。很多的
时候，我们沉迷于设计通用系统给我们带来的挑战之中，其实，我们所做的工作对用户而言是毫无意义的。架构的稳定架构简单化和架构的稳定性有什么关系吗？我
们说，架构越简单，其稳定性就越好。理由很简单，1个拥有4个方法和3个属性的类，和1个拥有20个方法和30属性的类相比，哪一个更稳定？当然是前者。
而架构最终都是要映射到代码级别上的，因此架构的简单将会带来架构的稳定。尽可能的让你的类小一些，尽可能的让你的方法短一些，尽可能的让类之间的关系少
一些。这并不是我的忠告，很多的设计类的文章都是这么说的。在这个话题上，我们可以进一步的阅读同类的文章（关于 refactoring
的思考）。辨正的简单因此，对我们来说，简单的意义就是不要把未来的、或不需要实现的功能加入到目前的软件中，相应的架构设计也不需要考虑这些额外的需
求，只要刚好能够满足当前的需求就好了。这就是简单的定义。可是在现实之中，总是有这样或者那样的原因，使得设计趋向复杂。一般来说，如果一个设计对团队
而言是有价值的，那么，付出一定的成本来研究、验证、发展、文档化这个设计是有意义的。反之，如果一个设计没有很大的价值或是发展它的成本超过了其能够提
供的价值，那就不需要去考虑这个设计。价值对不同的团队来说具有不同的含义。有时候可能是时间，有时候可能是用户价值，有时候可能是为了团队的设计积累和
代码重用，有时候是为了获得经验，有时候是为了研究出可重用的框架（FrameWork）。这些也可以称为目的，因此，你在设计架构时，请注意先确定好你
的目的，对实现目的有帮助的事情才考虑。 Scott
W.Ambler在他的文章中提到一个他亲身经历的故事，在软件开发的架构设计过程中，花了很多的时间来设计数据库到业务逻辑的映射架构，虽然这是一件任
何开发人员都乐意专研的事情（因为它很酷）。但他不得不承认，对用户来说，这种设计先进的架构是没有太大的意义的，因为用户并不关心具体的技术。当看到这
个故事的时候，我的触动很大。一个开发人员总是热衷于新奇的技术，但是如果这个新奇技术的成本由用户来承担，是不是合理呢？虽然新技术的采用能够为用户带
来效益，但是没有人计算过效益背后的成本。就我开发过的项目而言，这个成本往往是大于效益的。这个问题可能并没有确定的答案，只能是见仁见智了。
简单并不等于实现简单说到这里，如果大家有一个误解，认为一个简单的架构也一定是容易设计的，那就错了。简单的架构并不等于实现起来也简单。简单的架构需
要设计者花费大量的心血，也要求设计者对技术有很深的造诣。在我们正在进行的一个项目中，一开始设计的基础架构在实现中被修改了几次，但每修改一次，代码
量都减少一分，代码的可读性也就增强一分。从心理的角度上来说，对自己的架构进行不断的修改，确实是需要一定的勇气的。因为不论是设计还是代码，都是开发
人员的心血。但跨出这一步是值得的。右侧的例子讨论了Java的IO设计，Java类库的设计应该来说是非常优秀的，但是仍然避免不了重新的修改。实际
上，在软件开发领域，由于原先的设计失误而导致后来设计过于复杂的情况比比皆是（例如微软的OLE）。同样的，我们在设计软件的时候，也需要对设计进行不
断的修改。能够实现复杂功能，同时自身又简单的设计并不是一件容易的事情。简单设计需要什么样的设计师简单的架构需要全面的设计师。什么才是全面的设计
师，我的定义是既能够设计，又能够编码。我们在团队设计模式中就已经谈过象牙塔式架构和象牙塔式架构设计师。他们最容易犯的一个毛病就是设计和代码的脱
离。从我们自己的经验来看，即使在设计阶段考虑的非常完美的架构，在编码阶段也会出现这样或那样的问题。从而导致架构实现变得复杂。最明显的特征就是在编
码时出现了有大量方法的类，或是方法很长的类。这表明架构和代码脱钩了。在我们的开发过程中，不只一次出现这种现象，或者说，出现了坏味道（Bad
Smell）。Refactoring的技巧也同样有助于识别坏味道。一次的架构设计完成后，开发人员可以按照设计，快速的编程。可在一段时间之后，新的
特色不断的加入，我们发现代码开始混乱，代码量增大，可读性下降，调试变得困难，代码不可控制的征兆开始出现。我们就知道，架构的设计需要调整了。这属于
我们在后面所提到的Refactoring模式。而我们在这里要说的是，如果架构的设计师不参与编码，它是无法感受到坏味道的，因此也就不会主动的对设计
进行改进。要解决这个问题，最好的办法是让设计师参与代码的编写，尤其是重要架构的现实部分需要设计师的参与。如果设计师没有办法参与编码，那就需要一种
机制，能够把代码反馈给设计师，让他在适当的时候，重新考虑改进架构。一个可能的办法是Code
Review。让设计师审核代码，以确保编码者真正了解了架构设计的意图。例1.Java的IO系统从Java的IO系统设计中，我们可以感受到简单设计
的困难。
IO系统设计的困难性向来是公认的。Java的IO设计的一个目的就是使IO的使用简单化。在Java的1.0中，Java的IO系统主要是把IO系统分
为输入输出两个大部分，并分别定义了抽象类InputStream和OutputStream。从这两个的抽象类出发，实现了一系列不同功能的输入输出
类，同时，Java的IO系统还在输入输出中实现了FilterInputStream和FilterOutputStream的抽象类以及相关的一系列
实现，从而把不同的功能的输入输出函数连接在一起，实现复杂的功能。这个实现其实是Decorator模式（由于没有看过源码和相关的资料，这里仅仅是根
据功能和使用技巧推测，如果大家有不同的意见，欢迎来信讨论）。因此，我们可以把多个对象叠加在一起，提供复杂的功能： DataInpuStream
in = new DataInputStream( new BufferedInputStream( new
FileInputStream("test.txt");
上面的代码使用了两个FilterInputStream：DataInpuStream和BufferedInputStream，以实现读数据和缓冲
的功能，同时使用了一个InputStream：FileInputStream，从文件中读取流数据。虽然使用起来不是很方便，但是应该还是非常清晰的
设计。令设计混乱的是既不属于InputStream，也不属于OutputStream的类，例如RandomAccessFile，这正表明，由于功
能的复杂化，使得原先基于输入输出分类的设计变得混乱，根据我们的经验，我们说设计需要Refactoring了。因此，在Java1.1中，IO系统被
重新设计，采用了Reader和Writer位基础的设计，并增加了新的特性。但是目前的设计似乎更加混乱了，因为我们需要同时使用1.0和1.1两种不
同的IO设计。 例2. measurement pattern 在分析模式一书中有一个measurement
pattern（测量模式），原来它是为了要解决现实中各种各样纷繁复杂的可测量的属性。例如，一个医疗系统中，可能会有身高多高，体重多种，血压多少等
上千种可测量的属性。如果分别表示它们，必然导致系统复杂性的上升。因此measurement
pattern就从这些属性的可测量的共性出发，研究新的解决方法，提出了measurement
pattern的想法：如图所示，把可测量的属性（Measurement）做为Phenomenon
Type的实例，此外，每一个的Person可以拥有多个的Measurement，同时，Measurement还对应处理的属性，例如图中的
Quantity，就表示了Measurement的数量和单位。比如，一个人的体重是65公斤，那么，Phenomenon
Type就是体重，Quantity的amount是65，units是公斤。图 5.牋 measurement pattern
的类图这其实是一个很简单的设计，但它清楚的表示了属性之间的关系，简化了数千种的属性带来的复杂性。此外，我们进一步思考，就会发现，这种架构只是针对
目前出现属性众多的问题的基本解决方法，它还可以根据具体的需要进行扩展，例如，实现动态添加单位，或实现不同单位的转化等问题。因此，我们这里展示的其
实是一种思考的方法，假想一下，当你在面对一个复杂的医疗系统时，大量的属性和不同的处理方式，你是不是可以从这样复杂的需求中找出简单的部分来呢？在我
们架构设计的第一篇中，我们谈到架构设计的本质在于抽象，这里例子就是最典型的一个例子，在我们传统的想法中，我们都会把身高、体重等概念做为属性或是
类，但是为了满足这里的需求，我们对这些具体的概念做一个抽象，提出可测量类别的概念，并把它设计为类（Phenomenon
Type），而把具体的概念做为实例。这种抽象的思想在软件设计中无处不在，例如元类的概念。更深入的理解下一章中我们将会讨论迭代设计，其中还会涉及到
简单设计的相关知识。建议可以将两章的内容结合起来看。 迭代是一种软件开发的生命周期模型，在设计中应用迭代设计，我们可以得到很多的好处。
Context 在软件生命周期中，我们如何对待架构设计的发展？ Problem
架构设计往往发生在细节需求尚未完成的时候进行的。因此，随着项目的进行，需求还可能细化，可能变更。原先的架构肯定会有不足或错误的地方。那么，我们应
该如何对待原先的设计呢？我们在简单设计模式中简单提到了"Planned Design"和"Evolutionary
Design"的区别。XP社团的人们推崇使用"Evolutionary
Design"的方式，在外人看来，似乎拥护者们从来不需要架构的设计，他们采用的方式是一开始就进入代码的编写，然后用Refactoring来改进代
码的质量，解决未经设计导致的代码质量低下的功能。从一定程度上来说，这个观点并没有错，它强调了代码对软件的重要性，并通过一些技巧（如
Refactoring）来解决缺乏设计的问题。但我并不认同"Evolutionary
Design"的方式，在我看来，一定程度上的"Planned Design"是必须的，至少在中国的软件行业中，"Planned
Design"还没有成为主要的设计方向。借用一句明言，"凡事预则立，不预则废"，在软件设计初期，投入精力进行架构的设计是很有必要的，这个架构是你
在后续的设计、编码过程中依赖的基础。但是，一开始我们提到的设计改进的问题依然存在，我们如何解决它呢？在简单设计模式中，我们提到了设计改进的必要
性，但是，如果没有一种方法去控制设计的改进的话，那么设计改进本身就是一场噩梦。因此，何时改进，怎么改进， 如何控制，这都是我们需要面对的问题。
Solution
为了实现不断的改进，我们将在开发流程中引入迭代的概念。迭代的概念在我的另一篇文章－－《需求的实践》中已经提到，这里我们假设读者已经有了基本的迭代
的概念。软件编码之前的工作大致可以分为这样一个工作流程：上图中的流程隐含着一个信息的损失的过程。来自于用户的需求经过整理之后，开发人员就会从中去
掉一些信息，同样的事情发生在后面的过程中，信息丢失或变形的情况不断的发生。这里发生了什么问题？应该说，需求信息的失真是非常普遍的，我们缺少的是一
种有效的办法来抑止失真，换句话说，就是缺少反馈。如果把眼睛蒙上，那我们肯定没有办法走出一条很长的直线。我们走路的时候都是针对目标不断的调整自己的
方向的。同样的，漫长的软件开发过程如果没有一种反馈机制来调整方向，那最后的软件真是难以想象。所以我们引入了迭代周期。初始设计和迭代设计在团队设计
中，我们一直在强调，设计组最开始得到的设计一定只是一个原始架构，然后把这个原始架构传播到每一位开发者的手中，从而在开发团队中形成共同的愿景。（愿
景（Vision）：源自于管理学，表示未来的愿望和景象。这里借用来表示软件在开发人员心中的样子。在后面的文章中我们会有一个章节专门的讨论架构愿
景。）迭代（Iterate）设计，或者我们称之为增量（Incremental）设计的思想和XP提倡的Evolutionary
Design有异曲同工之妙。我们可以从XP、Crystal、RUP、ClearRoom等方法学中对比、体会迭代设计的精妙之处：每一次的迭代都是在
上一次迭代的基础上进行的，迭代将致力于重用、修改、增强目前的架构，以使架构越来越强壮。在软件生命周期的最后，我们除了得到软件，还得到了一个非常稳
定的架构。对于一个软件组织来说，这个架构很有可能就是下一个软件的投入或参考。我们可以把早期的原始架构当作第一次迭代前的早期投入，也可以把它做为第
一次迭代的重点，这些都是无所谓的。关键在于，原始架构对于后续的架构设计而言是非常重要的，我们讨论过架构是来源于需求的，但是原始架构应该来源于那些
比较稳定的需求。 TIP：现实中迭代设计退化为"Code and Fix"的设计的情况屡见不鲜（"Code and
Fix"参见简单设计）。从表面上看，两者的做法并没有太大的差别，都是针对原有的设计进行改进。但是，二者效果的差别是明显的："Code and
Fix"是混沌的，毫无方向感可言，每一次的改进只是给原先就已摇摇欲坠的积木上再加一块积木而已。而迭代设计的每一次改进都朝着一个稳定的目标在前进，
他给开发人员带来信心，而不是打击。在过程上，我们说迭代设计是在控制之下的。从实践的经验中，我们发现，把原该在目前就该解决的问题退后是造成这一问题
的主要原因之一。因此，请严格的对待每一次的迭代，确保计划已经完成、确保软件的质量、确保用户的需求得到满足，这样才是正统的迭代之路。
单次的迭代我们说，每一次的迭代其实是一个完整的小过程。也就是说，它同样要经历文章中讨论的这些过程模式。只不过，这些模式的工作量都不大，你甚至可以
在很短的时间内做完所有的事情。因此，我们好像又回到了文章的开头，重新讨论架构设计的过程。单次迭代最令我们兴奋的就是我们总是可以得到一个在当前迭代
中相当稳定的结果，而不像普通的架构设计那样，我们深怕架构会出现问题，但又不得不依赖这个架构。从我们的心理上来分析，我们是在持续的建设架构中，我们
不需要回避需求的变更，因为我们相信，在需求相对应的迭代中，我们会继续对架构进行改进。大家不要认为这种心理的改变是无关紧要的，我起初并没有意识到这
个问题，但是我很快发现新的架构设计过程仍然笼罩在原先的惧怕改变的阴影之下的时候，迭代设计很容易就退化为"Code and
Fix"的情形。开发人员难以接受新方法的主要原因还是在心理上。因此，我不得不花了很多的时间来和开发人员进行沟通，这就是我现实的经验。迭代的交错基
于我们对运筹学的一点经验，迭代设计之间肯定不是线性的关系。这样说的一个原因架构设计和后续的工作间还是时间差的。因此，我们不会傻到把时间浪费在等待
其它工作上。一般而言，当下一次迭代的需求开始之后，详细需求开始之前，我们就已经可以开始下一次迭代的架构设计了。各次迭代之间的时间距离要视项目的具
体情况而定。比如，人员比较紧张的项目中，主要的架构设计人员可能也要担任编码人员的角色，下一次迭代的架构设计就可能要等到编码工作的高峰期过了之后。
可是，多次的交错迭代就可能产生版本的问题。比如，本次的迭代的编码中发现了架构的一个问题，反馈给架构设计组，但是架构设计组已经根据伪修改的本次迭代
的架构开始了下一次迭代的架构设计，这时候就会出现不同的设计之间的冲突问题。这种情况当然可以通过加强对设计模型的管理和引入版本控制机制来解决，但肯
定会随之带来管理成本上升的问题，而这是不符合敏捷的思想的。这时候，团队设计就体现了他的威力了，这也是我们在团队设计中没有提到的一个原因。团队设计
通过完全的沟通，可以解决架构设计中存在冲突的问题。 迭代频率
XP提倡迭代周期越短越好（XP建议为一到两周），这是个不错的提议。在这么短的一个迭代周期内，我们花在架构设计上的时间可能就只有一两个小时到半天的
时间。这时候，会有一个很有意思的现象，你很难去区分架构设计和设计的概念了。因为在这么短的一个周期之内，完成的需求数量是很少的，可能就只有一两个用
例或用户素材。因此，这几项需求的设计是不是属于架构设计呢？如果是的话，由于开发过程是由多次的迭代组成的，那么开发过程中的设计不都属于架构设计了
吗？我们说，架构是一个相对的概念，是针对范围而言的，在传统的瀑布模型中，我们可以很容易的区分出架构设计和普通设计，如果我们把一次迭代看作是一个单
独的生命周期，那么，普通的设计在这样一个范围之内也就是架构设计，他们并没有什么两样。但是，迭代周期中的架构设计是要遵循一定的原则的，这我们在下面
还会提到。我们希望迭代频率越快越好，但是这还要根据现实的情况而定。比如数据仓库项目，在项目的初期阶段，我们不得不花费大量的时间来进行数据建模的工
作，这其实也是一项专门针对数据的架构设计，建立元数据，制定维，整理数据，这样子的过程很难分为多次的迭代周期来实现。如何确定软件的迭代周期可以说，
如果一支开发团队没有相关迭代的概念，那么这支团队要立刻实现时隔两周迭代周期是非常困难的，，同时也是毫无意义的。就像我们在上面讨论的，影响迭代周期
的因素很多，以至于我们那无法对迭代周期进行量化的定义。因此我们只能从定性的角度分析迭代周期的发展。另一个了解迭代的方法是阅读XP的相关资料，我认
为XP中关于迭代周期的使用是很不错的一种方法，只是他强调的如此短的迭代周期对于很多的软件团队而言都是难以实现的。迭代周期的引入一定是一个从粗糙到
精确的过程。迭代的本质其实是短周期的计划，因此这也是迭代周期越短对我们越有好处的一大原因，因为时间缩短了，计划的可预测性就增强了。我们知道，计划
的制定是依赖于已往的经验，如果原先我们没有制定计划或细节计划的经验，那么我们的计划就一定是非常粗糙，最后的误差也一定很大。但是这没有关系，每一次
的计划都会对下一次的计划产生正面的影响，等到经验足够的时候，计划将会非常的精确，最后的误差也会很小。迭代周期的确定需要依赖于单位工作量。单位工作
量指的是一定时间内你可以量化的最小的绩效。最简单的单位工作量是每位程序员一天的编码行数。可惜显示往往比较残酷，团队中不但有程序员的角色，还有设计
师、测试人员、文档制作人员等角色的存在，单纯的编码行数是不能够作为唯一的统计依据的。同样，只强调编码行数，也会导致其它的问题，例如代码质量。为了
保证统计的合理性，比较好的做法是一个团队实现某个功能所花费的天数作为单位工作量。这里讨论的内容实际是软件测量技术，如果有机会的话，再和大家探讨这
个问题。迭代周期和软件架构的改进我们应用迭代方法的最大的目的就是为了稳步的改进软件架构。因此，我们需要了解架构是如何在软件开发的过程中不断演进
的。在后面的文章中，我们会谈到用Refactoring的方法来改进软件架构，但是Refactoring的定义中强调，Refactoring必须在
不修改代码的外部功能的情况下进行。对于架构来说，我们可以近乎等价的认为就是在外部接口不变的情况下对架构进行改进。而在实际的开发中，除非非常有经
验，否则在软件开发全过程中保持所有的软件接口不变是一件非常困难的事情。因此，我们这里谈的架构的改进虽然和Refactoring有类似之处，但还是
有区别的。软件架构的改进在软件开发过程会经历一个振荡期，这个振荡期可能横跨了数个迭代周期，其间架构的设计将会经历剧烈的变化，但最后一定会取向于平
稳。（如果项目后期没有出现设计平稳化的情况，那么很不幸，你的项目注定要失败了，要么是时间的问题，要么就是需求的问题）。关键的问题在于，我们有没有
勇气，在架构需要改变的时候就毅然做出变化，而不是眼睁睁的看着问题变得越来越严重。最后的例子中，我们讨论三个迭代周期，假设我们在第二个周期的时候拒
绝对架构进行改变，那么第三个周期一定是有如噩梦一般。变化，才有可能成功。我们知道变化的重要性，但没有办法知道变化的确切时间。不过我们可以从开发过
程中嗅到架构需要变化的气味：当程序中重复的代码逐渐变多的时候，当某些类变得格外的臃肿的时候，当编码人员的编码速度开始下降的时候，当需求出现大量的
变动的时候。例子：从这一周开始，我和我的小组将要负责对软件项目中的表示层的设计。在这个迭代周期中，我们的任务是要为客户端提供6到10个的视图。由
于视图并不很多，表示层的架构设计非常的简单：准确的说，这里谈不上设计，只是简单让客户端访问不同的视图而已。当然，在设计的示意图中，我们并没有必要
画出所有的视图来，只要能够表达客户端和视图的关联性就可以了。（架构设计需要和具体的实现绑定，但是在这个例子中，为了着重体现设计的演进，因此把不必
要的信息都删掉。在实际的设计中，视图可能是JSP页面，也可能是一个窗口。）第一个迭代周的任务很快的完成了，小组负责的表示层模块也很顺利的和其它小
组完成了对接，一个简陋但能够运转的小系统顺利的发布。客户观看了这个系统的演示，对系统提出了修改和补充。第二个迭代周中，模块要处理的视图增加到了
30个，视图之间存在相同的部分，并且，负责数据层的小组对我们说，由于客户需求的改进，同一个视图中将会出现不同的数据源。由于我们的视图中直接使用了
数据层小组提供给我们的数据源的函数，这意味着我们的设计需要进行较大的调整。考虑到系统的视图的量大大的增加，我们有必要对视图进行集中的管理。前端控
制器（Front
Control）模式将会是一个不错的技巧。对于视图之间的普遍的重复部分，可以将视图划分为不同的子视图，再把子视图组合为各种各样的视图。这样我们就
可以使用组合（Composite）模式：客户的请求集中提交给控制器，控制器接受到客户的请求之后，根据一定的规则，来提供不同的视图来反馈给客户。控
制器是一个具有扩展能力的设计，目前的视图数量并不多，因此仍然可以使用控制器来直接分配视图。如果视图的处理规则比较复杂，我们还可以使用创建工厂
（Create Factory）模式来专门处理生成视图的问题。对于视图来说，使用组合模式，把多个不同数据源的视图组合为复杂的视图。</font></div>
<div><font size="3">&nbsp;</font></div>
<div><font size="3">例
如，一个JSP的页面中，可能需要分为头页面和尾页面。项目进入第三个迭代周期之后，表示层的需求进一步复杂化。我们需要处理权限信息、需要处理数据的合
法性判断、还需要面对更多的视图带来的复杂程度上升的问题。表示层的权限处理比较简单，我们可以从前端控制器中增加权限控制的模块。同时，为了解决合法性
判断问题，我们又增加了一个数据过滤链模块，来完成数据的合法性判断和转换的工作。为了不使得控制器部分的功能过于复杂，我们把原先属于控制器的视图分发
功能转移到新的分发器模块，而控制器专门负责用户请求、视图的控制。我们来回顾这个例子，从迭代周期1中的需求最为简单，其实，现实中的项目刚开始的需求
虽然未必会像例子中的那么简单，但一定不会过于复杂，因此迭代周期1的设计也非常的简单。到了迭代周期2的时候，需求开始变得复杂，按照原先的架构继续设
计的话，必然会导致很多的问题，因此对架构进行改进是必要的。我们看到，新的设计能够满足新的需求。同样的，迭代周期3的需求更加的复杂，因此设计也随之
演进。这就是我们在文章的开始提到的"Evolutionary Design"的演进的思想。 </font></div>
<div><hr />
</div>
<div><font face="Courier New" size="3"><strong>推荐书籍:</strong></font></div>
<div><strong><font face="Courier New" size="3">&nbsp;</font></strong></div>
<a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk506004&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk506004.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=zjbk347871&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_73000724880945323-fm.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk739046&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk739046.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk719523&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk719523.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk501196&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk501196.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=zjbk169864&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/n/noimg_sml.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk403206&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk403206.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk720372&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk720372.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.bookschina.com/union/ubook.asp?adservice=353172&amp;tourl=http://www.bookschina.com/192111.htm"><img alt="" src="http://www.bookschina.com/cover/80.00.00.00/S192111.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=zhbk000970&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_1305156f1.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk407004&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk407004.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk501196&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk501196.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=zjbk556997&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_7505862774001.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk407004&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk407004.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=zjbk160697&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_zjbk160697.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=bkbk505498&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_bkbk505498.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.amazon.cn/detail/product.asp?prodid=zjbk393975&amp;source=wangchinaking"><img alt="" src="http://images.amazon.cn/t/tn_720806461X0996144-fm.jpg" border="0" height="150" width="100" /></a> <a target="_blank" href="http://www.bookschina.com/union/ubook.asp?adservice=353172&amp;tourl=http://www.bookschina.com/308345.htm"><img alt="" src="http://www.bookschina.com/cover/80.00.00.00/S308345.jpg" border="0" height="150" width="100" /></a>
<img src ="http://www.blogjava.net/bill2004158/aggbug/172038.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bill2004158/" target="_blank">Bill Wang</a> 2008-01-01 23:43 <a href="http://www.blogjava.net/bill2004158/articles/172038.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>敏捷思维－架构设计中的方法学（4） </title><link>http://www.blogjava.net/bill2004158/articles/172037.html</link><dc:creator>Bill Wang</dc:creator><author>Bill Wang</author><pubDate>Tue, 01 Jan 2008 15:41:00 GMT</pubDate><guid>http://www.blogjava.net/bill2004158/articles/172037.html</guid><wfw:comment>http://www.blogjava.net/bill2004158/comments/172037.html</wfw:comment><comments>http://www.blogjava.net/bill2004158/articles/172037.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bill2004158/comments/commentRss/172037.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bill2004158/services/trackbacks/172037.html</trackback:ping><description><![CDATA[<center><font color="#000099"><strong>四、团队设计 </strong></font></center><br />
<br />
团队设计是敏捷方法论中很重要的一项实践。我们这里说的团队，指的并不是复数的人。一群人就是一群人，并没有办法构成团队。要想成为团队，有很多的工作要做。 <br />
<br />
我们之所以考虑以团队为单位来考虑架构设计，是因为软件开发本身就不是一件个人的事情，架构设计更是如此。单个人的思维不免有考虑欠妥之处，单个人的学识也不可能覆盖所有的学科。而组织有效的团队却能够弥补这些缺憾。 <br />
<br />
<strong>Context </strong><br />
<br />
谁来负责架构的设计？ <br />
<br />
<strong>Problem</strong> <br />
<br />
在我们的印象中，总认为架构设计是那些所谓架构设计师的专属工作，他们往往拥有丰富的设计经验和相关的技能，他们不用编写代码，就能够设计出理论上尽善尽美的架构，配有精美的图例。 <br />
<br />
问题1：理论上设计近乎完美的架构缺乏程序的证明，在实际应用中往往会出这样那样的问题。 <br />
<br />
问题2：设计师设计架构带有很大的主观性，往往会忽视客户的需求，导致架构无法满足需求。 <br />
<br />
问题3：实现的程序员对这种架构有抵触的情绪，或是因为不理解架构而导致架构实现的失败。 <br />
<br />
问题4：架构师设计架构主要是依据自己的大量经验，设计出的架构不能真实的反映目前的软件需要。 <br />
<br />
<strong>Solution</strong> <br />
<br />
团队设计的理论依据是群体决策。和个人决策相比，群体决策的最大好处就是其结论要更加的完整。而群体决策虽然有其优点，但其缺点也是很明显的：需要额外
付出沟通成本、决策效率低、责任不明确、等等。但是群体决策如果能够组织得当的话，是能够在架构设计中发挥很大的优势的。 <br />
<br />
<strong>避免象牙塔式的架构设计</strong> <br />
<br />
对软件来说，架构设计是一项至关重要的工作。这样的工作交给某个人是非常危险的。即便这个人再怎么聪明，他也可能会遗漏部分的细节。组织有效的团队的力量是大大超过个人的力量的，因此团队的成果较之个人的成果，在稳定性和思考的周密程度上，都要更胜一筹。 <br />
<br />
Scott W. Ambler在其著作中给出了象牙塔式架构（ivory tower architecture）的概念： <br />
<br />
An ivory tower architecture is one that is often developed by an
architect or architectural team in relative isolation to the day-to-day
development activities of your project team(s). <br />
<br />
中国现在的软件开发行业中也逐渐出现了象牙塔式的架构设计师。这些架构师并不参与实际的程序编写，他的工作就是为项目制作出精美的架构模型，这种架构模型在理论上是相当完美的。 <br />
<br />
例1：在XP中，我们基本上看不到架构设计的影子。并不是说采用XP技术的团队就不需要架构设计。XP不存在专门的设计时期，它提倡使用一些简单的图例、
比喻的方式来表达软件的架构，而这种的架构设计是无时无刻不在进行的。其实，XP中的设计采用的就是团队设计的方式，结队编程（Pair
Programming）和代码的集体所有制（Collective
Ownership）是团队设计的基础，也就是基于口述的沟通方式。通过采用这样的方式，XP几乎不需要文档来表达架构的设计。 <br />
<br />
优秀的架构师能够充分的利用现有框架，减少软件的投入，增强软件的稳定性。这些都没有错，但是问题在于&#8220;过犹不及&#8221;。象牙塔式架构师往往会出现文章开始指
出的那些问题。架构设计其实并不是非常复杂的工作，但它要求开发人员具备相关的技能、经验以及对问题域有一定的了解。开发人员往往都具有相关的技术技能
（编程、数据库设计、建模），而对问题域的理解可以从用户和行业专家那里获得帮助。因此，在理论上，我们要实现架构设计的团队化是完全可能的。 <br />
<br />
在上面的象牙塔式架构定义中，我们看到架构师和日常的开发工作是隔绝的。这样的设计出的架构有很大的局限性。在现实中，我们还会发现另外一种角色，他来
自于开发团队外部，为开发人员提供相关的技术或业务的培训。这种角色称为教练，在软件开发中是非常重要的角色，不能够和象牙塔式架构设计师之间画等号。
<br />
<br />
<strong>选择你的设计团队。</strong> <br />
<br />
软件的架构在软件的生命周期的全过程中都很重要，也就是说，软件开发团队中
的所有人员都需要和架构打交道。因此，最好的团队组织方式是所有开发人员都参与架构的设计，我们称这种方式为全员参与。全员参与的方式保证了所有开发人员
都能够对架构设计提出自己的见解，综合多方面的意见，在全体开发人员中达成一致。这种方式尤其适合于一些小的团队。 <br />
<br />
还是会有很多
的团队由于种种的原因不适合采用全员参与的方式。那么，组织优秀的开发人员组成设计组也是比较好的方式。一般，我们选择那些在项目中比较重要的，有较多开
发经验，或是理论扎实的那些人来组成设计组。当然，如果你考虑到为组织培养后续力量，你也可以让一些新手加入设计组，或是你觉得自己的开发力量不足，邀请
外部的咨询力量介入，这完全取决于具体的情况。 <br />
<br />
设计组不同于我们之前提到的象牙塔式架构设计师。设计组设计出来的架构只能称为原
始架构，它是需要不断的反馈和改进的。因此，在架构实现中，设计组的成员将会分布到开发团队的各个领域，把架构的思想带给所有开发人员，编写代码来检验架
构，并获得具体的反馈，然后所有的成员再集中到设计组中讨论架构的演进。 <br />
<br />
<strong>团队设计中存在的问题</strong> <br />
<br />
在团队设计的过程，我们会遇到各种各样的问题，首当其冲的就是沟通成本的问题。架构设计时，需求尚未被充分理解，软件的设计思路还处于萌发的状态。这样
的情况下，团队的每位成员对软件都有独特的见解，这些可能有些是相同的，有些是互斥的。就好比盲人摸象一样，他们的观点都代表了软件的一部分或是一方面，
但是没有办法代表软件的全部。 <br />
<br />
在敏捷方法论中，我们的每一个流程都是迅速进行、不断改进的。架构设计也是一样，我们不可能在一次架构设计上花费更多的时间。而团队决策总是倾向于较长的讨论和权衡。 <br />
<br />
例2中的问题在架构设计中时有发生，纯技术的讨论很容易上升称为争吵。这种情况几乎没有办法完全避免。团队型的决策必然会发生观念的冲突。控制一定程度
内的观念的冲突对团队的决策是有益，但是如果超出了这个程度就意味着失控了，需要团队领导者的调节。而更重要的，我们需要注意沟通的技巧： <br />
<br />
<strong>团队沟通</strong> <br />
<br />
团队进行架构设计的时候沟通是一个非常需要注意的问题，上述的情境在软件组织中是经常发生的，因为技术人员很自然认为自己的技术比别人的好，如果自己的
技术受到质疑，那怕对方是抱着讨论的态度，也无异于自身的权威受到了挑战，面子是无论如何都需要捍卫的。而沟通如果带上了这样一层主观色彩，那么沟通信息
的受众就会潜意识的拒绝接受信息。相反，他会找出对方话语中的漏洞，准备进行反击。因此，我们要注意培养一种良好的沟通氛围。 <br />
<br />
在
实际的观察中，我发现团队沟通中存在两种角色，一种是建议者，他们经常能够提出建议。一种是质疑者，他们对建议提出否定性的看法。这两种角色是可能互换
的，现在的建议者可能就是刚才的质疑者。质疑者的发言是很能打击建议者的积极性的，而在一个脑力激荡的会议中，最好是大家都能够扮演建议者的角色，这就要
求沟通会议的主持者能够掌握好这一点，对建议给予肯定的评价，并鼓励大家提出新的建议。 <br />
<br />
例2：敏捷方法非常注重的就是团队的沟通。沟通是一个很有意思的话题，讲起来会花费大量的时间，我们这里只是针对架构设计中可能存在的沟通问题做一个简单的讨论。我们这里假设一个讨论情境，这个情境来源于真实的生活： <br />
<br />
项目主管徐辉、设计师李浩、设计师罗亦明正在讨论一个新的软件架构。 <br />
<br />
"李浩你认为这个软件数据库连接部分应该如何考虑？"徐辉问。 <br />
<br />
李浩想了想，"我觉得方案A不错&#8230;" "方案A肯定有问题！这个软件和上一次的又不同。"罗亦明打断了李浩的发言。 <br />
<br />
"你懂什么！你到公司才多久，方案A是经过很长时间的证明的！"发言被打断，李浩有点恼火，罗亦明进入公司没有多久，但在一些事情上老是和他唱反调。 <br />
<br />
"我进公司多久和方案A的错误有什么关系！" <br />
<br />
在这样一种氛围中，会议的结果可想而知。 <br />
<br />
良好的沟通有助于架构设计工作的开展。一个成员的能力平平的团队，可以藉由良好的沟通，设计出优秀的架构，而一个拥有一个优秀成员的团队，如果缺乏沟通，最后可能连设计都出不来。这种例子现实中可以找到很多。 <br />
<br />
<strong>标准和风格</strong> <br />
<br />
我们总是在不知不觉之中使用各种各样的标准和风格。在团队设计中，我们为了提高决策的效率，可以考虑使用统一的标准和风格。统一的标准和风格并不是一朝
一夕形成的。因为每个人都有自己不同的习惯和经历，强制性的要求开发人员使用统一的标准（风格）容易引起开发人员的不满。因此在操作上需要注意技巧。对架
构设计而言，比较重要的标准（风格）包括以下的这些类别： <br />
<br />
<strong>&#183;</strong>界面设计 <br />
<br />
<strong>&#183;</strong>流程设计 <br />
<br />
<strong>&#183;</strong>建模规范 <br />
<br />
<strong>&#183;</strong>编码规范 <br />
<br />
<strong>&#183;</strong>持久层设计 <br />
<br />
<strong>&#183;</strong>测试数据 <br />
<br />
在我的经验中，有一些组织平时并不注意标准（风格）的积累，认为这种积累属于雕虫小技，但正是这些小技，能够非常有效的提高沟通的效率和降低开发人员的
学习曲线。试想一下，如果一个团队中所有人写出的代码都是不同标准和风格的，那么理解起来肯定会困难许多。当然，我们没有必要自己开发一套标准（风格）出
来，现实中有很多可以直接借用的资料。最好的标准是UML语言，我们可以从UML的官方网站下载到最新的规范，常用的编码标准更是随处可见。不过虽然有了
统一的标准，如果风格不统一，同样会造成沟通的障碍。例如下图显示的类图，虽然它们表示的是同一个类，但是由于版型、可视性、详细程度的差别，看起来又很
大的差别。而在其它的标准中，这种差别也是普遍存在的。因此，我们在使用了统一的标准之后，还应该使用同样的风格。Scott W.
Ambler专门成立了一个网站讨论UML的建模风格的相关问题，有兴趣的读者可以做额外的阅读。 <br />
<br />
图 4. 两种风格的类图 <br />
<br />
<img src="http://developer.ccidnet.com/pub/attachment/2003/5/185071.jpg"  alt="" /> <br />
<br />
在统一的风格的基础上更进一步的是使用术语。使用沟通双方都了解专门的术语，可以代表大量的信息。最好的术语的范例就是设计模式的模式名。如果沟通的双
方都了解设计模式，那么一方只需要说这部分的设计可以使用工厂模式，另一方就能够理解，而不用再详细的解释设计的思路。这种的沟通方式是最高效的，但它所
需要的学习曲线也会比较陡。 <br />
<br />
<strong>团队设计的四明确</strong> <br />
<br />
为了最大程度的提高团队设计的高效性，可以从4个方面来考虑： <br />
<br />
1、明确目标 <br />
<br />
泛泛的召开架构讨论会议是没有什么意义的，一个没有鲜明主题的会议也不会有什么结果。在源自需求的模式中，我们谈到说可以有非功能需求的架构，可以有功
能需求的架构。因此，在进行团队设计之前，我们首先也需要确定，此次要解决什么问题，是讨论业务逻辑的架构，还是技术架构；是全局性的架构，还是各模块的
架构。 <br />
<br />
2、明确分工 <br />
<br />
我们之所以重视团队，很重要的额一个原因就是不同的成员有不同的擅长的区域。有些成员
可能擅长于业务逻辑的建模，有的擅长于原型设计，有的擅长于数据库设计，有的则擅长于Web编程。你能够想象一个软件没有界面吗？（有些软件可能是这种情
况）你能够想象一个软件只有数据库，而没有处理逻辑吗？因此，架构设计就需要综合的考虑各个方面，充分利用成员的优势。这就要求团队的各个成员都能够明确
自己的分工。 <br />
<br />
3、明确责权 <br />
<br />
除了明确自己的分工，每位成员都需要清楚自己的责任。没有责任，分工就不会有任
何的效力。每位成员都需要明确自己要做些什么。当然，和责任相对的，没有成员还需要知道自己的权力是什么。这些清楚了，进行高效的沟通的前提就具备了。每
次架构的讨论下来，每个人都清楚，自己要做些什么，自己需要要求其他人做些什么，自己该对谁负责。如果这些问题回答不了，那这次的讨论就白费了。 <br />
<br />
4、明确沟通方式 <br />
<br />
这里使用沟通方式可能有一点点不恰当，为了明确的表达意思，大家可以考虑信息流这个词。一个完整架构包括几个方面，分别都由那些人负责，如何产生，产生
的整个过程应该是什么样的？这样的一个信息流程，囊括了上面提到的三个明确。如果团队的每一个人都能够为架构的产生而努力，并顺利的设计出架构，那么这样
的流程是完美的。如果你发现其中的一些人不知道做些什么，那么，这就是流程出问题的现象了。完美的流程还会有一个额外的副产品，架构产生之后，团队对于软
件的设计已经是非常的清晰了。因为我们提倡的是尽可能多的开发人员参与架构的设计。 <br />
<br />
<strong>不仅仅是架构</strong> <br />
<br />
讨论到这里，其实有很多的内容已经脱离了架构设计了。也就是说，很多的原则和技巧都是可以用于软件开发的其它活动的。至于哪一些活动能够利用这些方法呢？大家可以结合自己的实际情况，来思考这个问题。提示一点，关键的入手处在于目前效率较低之处。
<img src ="http://www.blogjava.net/bill2004158/aggbug/172037.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bill2004158/" target="_blank">Bill Wang</a> 2008-01-01 23:41 <a href="http://www.blogjava.net/bill2004158/articles/172037.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【收藏】软件的架构与设计模式之什么是架构</title><link>http://www.blogjava.net/bill2004158/articles/172036.html</link><dc:creator>Bill Wang</dc:creator><author>Bill Wang</author><pubDate>Tue, 01 Jan 2008 15:39:00 GMT</pubDate><guid>http://www.blogjava.net/bill2004158/articles/172036.html</guid><wfw:comment>http://www.blogjava.net/bill2004158/comments/172036.html</wfw:comment><comments>http://www.blogjava.net/bill2004158/articles/172036.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bill2004158/comments/commentRss/172036.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bill2004158/services/trackbacks/172036.html</trackback:ping><description><![CDATA[		什么是软件系统的架构（Architecture）？一般而言，架构有两个要素：<br />
<br />
&#183;它是一个软件系统从整体到部分的最高层次的划分。<br />
<br />
一个系统通常是由元件组成的，而这些元件如何形成、相互之间如何发生作用，则是关于这个系统本身结构的重要信息。<br />
<br />
详细地说，就是要包括架构元件（Architecture Component）、联结器（<a class="bluekey" href="http://www.yesky.com/key/492/125492.html" target="_blank">Connector</a>）、任务流（<a class="bluekey" href="http://www.yesky.com/key/2221/162221.html" target="_blank">Task</a>-flow）。所谓架构元素，也就是组成系统的核心"砖瓦"，而联结器则描述这些元件之间通讯的路径、通讯的机制、通讯的预期结果，任务流则描述系统如何使用这些元件和联结器完成某一项需求。<br />
<br />
&#183;建造一个系统所作出的最高层次的、以后难以更改的，商业的和技术的决定。<br />
<br />
在建造一个系统之前会有很多的重要决定需要事先作出，而一旦系统开始进行详细设计甚至建造，这些决定就很难更改甚至无法更改。显然，这样的决定必定是有关系统设计成败的最重要决定，必须经过非常慎重的研究和考察。<br />
<br />
计算机软件的历史开始于五十年代，历史非常短暂，而相比之下建筑工程则从石器时代就开始了，人类在几千年的建筑设计实践中积累了大量的经验和教训。建筑设计基本上包含两点，一是建筑风格，二是建筑模式。独特的建筑风格和恰当选择的建筑模式，可以使一个独一无二。<br />
<br />
下面的照片显示了<a class="bluekey" href="http://www.yesky.com/key/2013/157013.html" target="_blank">中美</a>洲古代玛雅建筑，Chichen-Itza大金字塔，九个巨大的石级堆垒而上，九十一级台阶（象征着四季的天数）夺路而出，塔顶的神殿耸入云天。所有的数字都如日历般严谨，风格雄浑。难以想象这是石器时代的建筑物。<br />
<br />
<table align="center" border="0" width="90%">
    <tbody>
        <tr>
            <td>
            <div align="center"><img src="http://dev.yesky.com/imagelist/05/06/5tya4wd73n14.jpg" alt="" border="0" /><br />
            图1、位于<a class="bluekey" href="http://www.yesky.com/key/87/155087.html" target="_blank">墨西哥</a>Chichen-Itza（在玛雅语中chi意为嘴chen意为井）的古玛雅建筑。（摄影：作者）</div>
            </td>
        </tr>
    </tbody>
</table>
<br />
软件与人类的关系是架构师必须面对的核心问题，也是自从软件进入历史舞台之后就出现的问题。与此类似地，自从有了建筑以来，建筑与人类的关系就一直是建筑设计师必须面对的核心问题。<a class="bluekey" href="http://www.yesky.com/key/2396/147396.html" target="_blank">英国</a>首相丘吉尔说，我们<a class="bluekey" href="http://www.yesky.com/key/4434/164434.html" target="_blank">构造</a>建
筑物，然后建筑物构造我们（We shape our buildings, and afterwards our buildings shape
us）。英国下议院的会议厅较狭窄，无法使所有的下议院议员面向同一个方向入座，而必须分成两侧入座。丘吉尔认为，议员们入座的时候自然会选择与自己政见
相同的人同时入座，而这就是英国政党制的起源。Party这个词的原意就是"方"、"面"。政党起源的关键就是建筑物对人的影响。<br />
<br />
在软件设计界曾经有很多人认为功能是最为重要的，形式必须服从功能。与此类似地，在建筑学界，现代主义建筑流派的开创人之一Louis Sullivan也认为形式应当服从于功能（Forms follows function）。<br />
<br />
几乎所有的软件设计理念都可以在浩如烟海的建筑<a class="bluekey" href="http://www.yesky.com/key/3876/163876.html" target="_blank">学历</a>史中找到更为遥远的历史回响。最为著名的，当然就是模式理论和XP理论。<br />
<br />
<strong>架构的目标是什么</strong><br />
<br />
正如同软件本身有其要达到的目标一样，架构设计要达到的目标是什么呢？一般而言，软件架构设计要达到如下的目标：<br />
<br />
&#183;可靠性（Reliable）。软件系统对于用户的商业经营和管理来说极为重要，因此软件系统必须非常可靠。<br />
<br />
&#183;安全行（<a class="bluekey" href="http://www.yesky.com/key/1784/161784.html" target="_blank">Secure</a>）。软件系统所承担的交易的<a class="bluekey" href="http://www.yesky.com/key/2520/167520.html" target="_blank">商业价值</a>极高，系统的<a class="bluekey" href="http://www.yesky.com/key/1714/161714.html" target="_blank">安全性</a>非常重要。<br />
<br />
&#183;可扩展性（Scalable）。软件必须能够在用户的使用率、用户的数目增加很快的情况下，保持合理的性能。只有这样，才能适应用户的市场扩展得可能性。 <br />
<br />
&#183;可定制化（Customizable）。同样的一套软件，可以根据客户群的不同和市场需求的变化进行调整。<br />
<br />
&#183;可扩展性（Extensible）。在新技术出现的时候，一个软件系统应当允许导入新技术，从而对现有系统进行功能和性能的扩展<br />
<br />
&#183;可维护性（Maintainable）。软件系统的维护包括两方面，一是排除现有的<a class="bluekey" href="http://www.yesky.com/key/1048/166048.html" target="_blank">错误，</a>二是将新的软件需求反映到现有系统中去。一个易于维护的系统可以有效地降低技术支持的花费<br />
<br />
&#183;客户体验（Customer Experience）。软件系统必须易于使用。<br />
<br />
&#183;市场时机（<a class="bluekey" href="http://www.yesky.com/key/4453/159453.html" target="_blank">Time</a> to Market）。软件用户要面临同业竞争，软件提供商也要面临同业竞争。以最快的速度争夺市场先机非常重要。<br />
<br />
<strong>架构的种类</strong><br />
<br />
根据我们关注的角度不同，可以将架构分成三种：<br />
<br />
&#183;逻辑架构、软件系统中元件之间的关系，比如用户界面，数据库，外部系统接口，商业逻辑元件，等等。<br />
<br />
比如下面就是笔者亲身经历过的一个软件系统的逻辑架构图<br />
<br />
<table align="center" border="0" width="90%">
    <tbody>
        <tr>
            <td>
            <div align="center"><img src="http://dev.yesky.com/imagelist/05/06/619a7y8bhq8n.jpg" alt="" border="0" /><br />
            图2、一个逻辑架构的例子</div>
            </td>
        </tr>
    </tbody>
</table>
<br />
从上面这张图中可以看出，此系统被划分成三个逻辑层次，即表象层次，商业层次和数据持久层次。每一个层次都含有多个逻辑元件。比如<a class="bluekey" href="http://www.yesky.com/key/2606/137606.html" target="_blank">WEB服务</a>器层次中有<a class="bluekey" href="http://www.yesky.com/key/1130/136130.html" target="_blank">HTML</a>服务元件、Session服务元件、<a class="bluekey" href="http://www.yesky.com/key/3273/153273.html" target="_blank">安全服务</a>元件、<a class="bluekey" href="http://www.yesky.com/key/104/135104.html" target="_blank">系统管理</a>元件等。<br />
<br />
&#183;物理架构、软件元件是怎样放到硬件上的。<br />
<br />
比如下面这张物理架构图描述了一个分布于北京和上海的<a class="bluekey" href="http://www.yesky.com/key/2671/147671.html" target="_blank">分布式</a>系统的物理架构，图中所有的元件都是物理设备，包括网络分流器、代理服务器、<a class="bluekey" href="http://www.yesky.com/key/3771/148771.html" target="_blank">WEB服务</a>器、应用服务器、报表服务器、整合服务器、<a class="bluekey" href="http://www.yesky.com/key/3313/163313.html" target="_blank">存储服务</a>器、主机等等。<br />
<br />
<table align="center" border="0" width="90%">
    <tbody>
        <tr>
            <td>
            <div align="center"><img src="http://dev.yesky.com/imagelist/05/06/1u0j42w1et1m.jpg" alt="" border="0" /><br />
            图3、一个物理架构的例子</div>
            </td>
        </tr>
    </tbody>
</table>
<br />
&#183;系统架构、系统的非功能性特征，如可扩展性、可靠性、强壮性、灵活性、性能等。<br />
<br />
系统架构的设计要求架构师具备软件和硬件的功能和性能的过硬知识，这一工作无疑是架构设计工作中最为困难的工作。<br />
<br />
此外，从每一个角度上看，都可以看到架构的两要素：元件划分和设计决定。 <br />
<br />
首先，一个软件系统中的元件首先是逻辑元件。这些逻辑元件如何放到硬件上，以及这些元件如何为整个系统的可扩展性、可靠性、强壮性、灵活性、性能等做出贡献，是非常重要的信息。<br />
<br />
其次，进行软件设计需要做出的决定中，必然会包括逻辑结构、物理结构，以及它们如何影响到系统的所有非功能性特征。这些决定中会有很多是一旦作出，就很难更改的。<br />
<br />
根据作者的经验，一个基于数据库的系统架构，有多少个数据表，就会有多少页的架构设计文档。比如一个中等的<a class="bluekey" href="http://www.yesky.com/key/2936/147936.html" target="_blank">数据库应用</a>系统通常含有一百个左右的数据表，这样的一个系统设计通常需要有一百页左右的架构设计文档。 <br />
<br />
<strong>架构师</strong><br />
<br />
软体设计师中有一些技术水平较高、经验较为丰富的人，他们需要承担软件系统的架构设计，也就是需要设计系统的元件如何划分、元件之间如何发生相互作用，以及系统中逻辑的、物理的、系统的重要决定的作出。<br />
<br />
这样的人就是所谓的架构师（Architect）。在很多公司中，架构师不是一个专门的和正式的职务。通常在一个开发小组中，最有经验的程序员会负责一些架构方面的工作。在一个部门中，最有经验的项目经理会负责一些架构方面的工作。<br />
<br />
但是，越来越多的公司体认到架构工作的重要性，并且在不同的组织层次上设置专门的架构师位置，由他们负责不同层次上的逻辑架构、物理架构、系统架构的设计、配置、维护等工作。
<img src ="http://www.blogjava.net/bill2004158/aggbug/172036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bill2004158/" target="_blank">Bill Wang</a> 2008-01-01 23:39 <a href="http://www.blogjava.net/bill2004158/articles/172036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>架构师的启蒙战歌 </title><link>http://www.blogjava.net/bill2004158/articles/172035.html</link><dc:creator>Bill Wang</dc:creator><author>Bill Wang</author><pubDate>Tue, 01 Jan 2008 15:36:00 GMT</pubDate><guid>http://www.blogjava.net/bill2004158/articles/172035.html</guid><wfw:comment>http://www.blogjava.net/bill2004158/comments/172035.html</wfw:comment><comments>http://www.blogjava.net/bill2004158/articles/172035.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bill2004158/comments/commentRss/172035.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bill2004158/services/trackbacks/172035.html</trackback:ping><description><![CDATA[<p>作者：<a temp_href="http://blog.csdn.net/calvin/" href="http://blog.csdn.net/calvin/">江南白衣</a>，转载请保留。&nbsp;</p>
<p>下面几个What的问题是架构师的入门Question。</p>
<p><strong>1.什么是架构？</strong><br />
&nbsp; 如果自问自答，这是个相当鸡肋的问题。看看书里的答案可能有点收获。<br />
&nbsp; 架构定义了系统元素的结构与行为，关注最重要的元素，记录决策原理，受涉众利益与环境的影响。<br />
&nbsp;&nbsp;架构不仅是结构，也不是企业架构，系统架构，信息架构，硬件架构.....<br />
&nbsp; 架构设计也不是面向对象分析/设计，虽然架构设计基于面向对象设计，但补充了面向对象设计里没有关注的视点。</p>
<p><strong>2.架构有什么用途？<br />
</strong>&nbsp; 人类所有行为都是目的驱动的，不同目的下架构的过程也会不同，继续看书里的答案，经常的用途有：</p>
<ul>
    <li>培训与沟通 </li>
    <li>满足系统的质量属性，与涉众沟通达成一致的目标 </li>
    <li>有效管理复杂性 </li>
    <li>支持开发日程安排、工作分配、成本分析 </li>
</ul>
<p><strong>3.各个流派用什么视图来表达架构？<br />
</strong>&nbsp;&nbsp;
最经典的RUP 4+1，ISO/ITU-T联合制定的RM-ODP，Hofmeister在《Applied Software
Architecture》中使用的西门子视图，《Documenting Software Architectures》使用的方法等。</p>
<p><strong>4.架构师在软件生命周期中的工作和角色？<br />
&nbsp;&nbsp; </strong>架构师的工作不只是设计(虽然最重要的的确如是），在分析、设计、实现、测试、维护、技术风险管理、问题域分析、团队技术领导与沟通者等流程里架构师都有自己的角色要担当。</p>
<p><strong>5..架构师的技能？</strong><br />
&nbsp; 自己总结了一篇<a href="http://blog.csdn.net/calvinxiu/archive/2007/02/18/1511545.aspx">《<font color="#000000">架构师核心技能养成计划</font>》</a></p>
<p><strong>答案：</strong><br />
1.IBM DW 中文站上有四篇不错的入门文章：<br />
一、<a href="http://www.ibm.com/developerworks/cn/rational/rationaledge/content/mar06/eeles/">什么是软件架构？</a> <br />
二、<a href="http://www.ibm.com/developerworks/cn/rational/rationaledge/content/apr06/eeles/">软件构架师的特点</a> <br />
三、<a href="http://www.ibm.com/developerworks/cn/rational/rationaledge/content/may06/eeles/">软件架构的过程</a><br />
四、<a href="http://www.ibm.com/developerworks/cn/rational/rationaledge/content/jun06/eeles/">进行软件架构设计的益处</a>&nbsp; </p>
<p>2.《Large-Scale Software Architecture》的前50页也回答了同样的问题。</p>
<p>3. 另外所有和架构沾点边的书都会忍不住浪费篇幅去讨论这些问题。</p>
<p>&nbsp;&nbsp;&nbsp; 不过这些答案从字面上看都是大家熟悉的东西，很容易泛泛的看完了，过一阵子脑子里又十室九空，最好是能够看进去产出化学作用，再辛苦一点把它们总结成自己的文档。</p>
<p>And then? 可以开始一些How的问题了.....</p>
<img src ="http://www.blogjava.net/bill2004158/aggbug/172035.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bill2004158/" target="_blank">Bill Wang</a> 2008-01-01 23:36 <a href="http://www.blogjava.net/bill2004158/articles/172035.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>架构师书单 2nd Edition </title><link>http://www.blogjava.net/bill2004158/articles/172034.html</link><dc:creator>Bill Wang</dc:creator><author>Bill Wang</author><pubDate>Tue, 01 Jan 2008 15:32:00 GMT</pubDate><guid>http://www.blogjava.net/bill2004158/articles/172034.html</guid><wfw:comment>http://www.blogjava.net/bill2004158/comments/172034.html</wfw:comment><comments>http://www.blogjava.net/bill2004158/articles/172034.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/bill2004158/comments/commentRss/172034.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/bill2004158/services/trackbacks/172034.html</trackback:ping><description><![CDATA[<p>作者：<a href="http://blog.csdn.net/calvin/" temp_href="http://blog.csdn.net/calvin/">江南白衣</a>，原文出处： <a href="http://blog.csdn.net/calvinxiu/archive/2007/03/06/1522032.aspx" temp_href="http://blog.csdn.net/calvinxiu/archive/2007/03/06/1522032.aspx">http://blog.csdn.net/calvinxiu/archive/2007/03/06/1522032.aspx</a><br />
<br />
&nbsp;&nbsp;&nbsp;为了2007年的目标，列了下面待读或重读的书单。&nbsp;<br />
&nbsp;&nbsp;
"其实中国程序员，现在最需要的是一张安静的书桌。"，的确，中国架构师大多缺乏系统的基础知识，与其自欺欺人的宣扬"读书无用，重在实践变通，修身立命哲学书更重要"，把大好时间用来追逐互联网上的片言只语，不如直面缺陷，系统的学习一次。</p>
<p>&nbsp;&nbsp;&nbsp; 书单越读越薄，好书真的不多哇。</p>
<h2>&nbsp;&nbsp; 一、Software Architecture篇</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp;
这个领域没有什么"畅销书"，可能读者中本来就是开发设计人员与项目经理占了多数，真正定位为架构师而且做的也是架构师工作的不多吧，你懂的尽是偏僻的人生。</p>
<p>&nbsp;<strong>《Software Architecture in Practice,2nd
Edition--软件构架实践(第2版)》</strong></p>
<p>&nbsp;&nbsp; 第一版是第九届JOLT作品，一本被引用很多的架构书。</p>
<p><strong>《Documenting Software Architectures --软件构架编档》</strong></p>
<p>&nbsp;&nbsp;&nbsp;第13届JOLT大奖作品，捕获架构的过程，<a id="AjaxHolder_Comments_CommentList_ctl16_NameLink" target="_blank">徐昊</a>推荐。</p>
<p><strong>《Applied Software Architecture --实用软件体系结构》</strong></p>
<p><strong>&nbsp;&nbsp;</strong> 另一本被引用很多的架构之书。<br />
<br />
<br />
<img alt="" src="http://ec1.images-amazon.com/images/P/0321154959.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com/Book/BookImage/21/TS_730208042801top.jpg" /><br />
<img alt="" src="http://ec1.images-amazon.com/images/P/0201703726.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0201703726.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com/book/images/TS0012776top.jpg" temp_src="http://www.dearbook.com/book/images/TS0012776top.jpg" /></p>
<p><img alt="" src="http://ec1.images-amazon.com/images/P/0201325713.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com/book/BookImage/32/lastTS0032221__.jpg" /><br />
</p>
<h2>&nbsp;</h2>
<h2>二、UML 篇</h2>
<p>&nbsp; UML、4+1视图始终是架构师界最通用的东西，寻找一种向世界妥协的方式。<br />
<strong><br />
&nbsp;1.&nbsp;《<font face="Arial">UML Distilled 3rd</font>》</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 没什么特别想推荐的UML工具书，选本最薄的吧。</p>
<p><strong>&nbsp;2.《<font face="Arial">The Elements of UML 2.0
Style</font>》</strong></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; 胜在没有同类书。</p>
<p><strong>&nbsp;3.《UML和模式应用(第3版)--Applying UML and Patterns 3rd》</strong><br />
&nbsp;&nbsp;
UML+RUP作的OOAD过程。</p>
<p><br />
<img alt="" src="http://ec1.images-amazon.com/images/P/0131489062.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com/book/BookImage/lastTS00107202__.jpg" /></p>
<h2>三、特定领域篇</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp;开发人员有GOF23 Pattern，架构师同样也有架构师的Pattern。不同领域的架构师需要不同的知识。<br />
<strong>1.
公共领域<br />
</strong><strong>《Domain-Specific Application Frameworks
--特定领域应用框架：行业的框架体验》<br />
</strong>&nbsp;
ozzzzzz推荐，介绍了30个特定领域特定框架的设计。<br />
<br />
<strong>《Head First Design
Patterns》&nbsp;<br />
</strong>&nbsp;&nbsp;最好的GOF23经典设计模式阐释，适合被[GAMMA95]折磨的架构师拿来复习，中文版即将发行。<br />
<br />
<strong><img alt="" src="http://ec1.images-amazon.com/images/P/0471332801.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0471332801.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com.cn/Book/BookImage/23/TS_tdn01top.jpg" temp_src="http://www.dearbook.com.cn/Book/BookImage/23/TS_tdn01top.jpg" />&nbsp;
<br />
<br />
<img alt="" src="http://ec2.images-amazon.com/images/P/0596007124.01._AA240_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/0596007124.01._AA240_SCLZZZZZZZ_.jpg" /><br />
<br />
2.
Java EE领域</strong>&nbsp;<br />
<strong>&nbsp; 《Patterns of Enterprise Application
Architecture --企业应用架构模式》 <br />
&nbsp;&nbsp;&nbsp;&nbsp; </strong>&nbsp;Martin
Fowler老书，企业应用各层上的模式。&nbsp;&nbsp;<strong>&nbsp;<br />
&nbsp;&nbsp;</strong><br />
<strong>&nbsp; 《Effective
Enterprise Java--中文版》</strong>&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Neward,
Ted作品，作者学贯东西(.Net与Java)，像写Blog一样，每一页里面都有大量的信息。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 可惜两本都比较旧了，没有新版。</p>
<p><img alt="" src="http://ec1.images-amazon.com/images/P/0321127420.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0321127420.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com/Book/BookImage/22/TS_711114305101top.jpg" temp_src="http://www.dearbook.com/Book/BookImage/22/TS_711114305101top.jpg" />&nbsp;&nbsp;<br />
<br />
<img alt="" src="http://ec2.images-amazon.com/images/P/0321130006.01._AA240_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/0321130006.01._AA240_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com.cn/Book/BookImage/30/TS_711117114001top.jpg" temp_src="http://www.dearbook.com.cn/Book/BookImage/30/TS_711117114001top.jpg" /><br />
<br />
<strong><br />
3.
EAI/SOA领域&nbsp;<br />
</strong><strong>《Enterprise Integration Patterns
--企业集成模式：设计、构建及部署消息传递解决方案》</strong></p>
<p><br />
<img alt="" src="http://ec1.images-amazon.com/images/P/0321200683.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0321200683.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com/book/BookImage/lastTS00106277__.jpg" temp_src="http://www.dearbook.com/book/BookImage/lastTS00106277__.jpg" />&nbsp;
<br />
<br />
<br />
<br />
<strong>4. 网络与后台服务编程领域<br />
</strong><strong>《Pattern-Oriented
Software Architecture, Volume 2 --面向模式的软件体系结构
卷2:用于并发和网络化对象的模式》<br />
<br />
《Pattern-Oriented Software Architecture, Volume&nbsp;3
</strong><strong>--面向模式的软件体系结构卷3：资源管理模式》</strong></p>
<p><strong>&nbsp;&nbsp;&nbsp;&nbsp;</strong>著名的POSA2与POSA3。<br />
<img alt="" src="http://ec1.images-amazon.com/images/P/0471606952.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0471606952.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com.cn/book/images/TS0012515top.jpg" temp_src="http://www.dearbook.com.cn/book/images/TS0012515top.jpg" />&nbsp; <br />
<img alt="" src="http://ec2.images-amazon.com/images/P/0470845252.01._AA240_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/0470845252.01._AA240_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com.cn/book/BookImage/35/lastTS0044414__.jpg" temp_src="http://www.dearbook.com.cn/book/BookImage/35/lastTS0044414__.jpg" />&nbsp;
<br />
</p>
<h2>四、闲书篇</h2>
<p><strong>《Code Complete 2 --代码大全2》</strong>&nbsp;<br />
&nbsp;&nbsp; 一本你教育小弟时的代言人。</p>
<p><strong>《The Pragmatic Programmer --程序员修炼之道：从小工到专家》</strong>&nbsp;<br />
<strong>&nbsp;&nbsp;
</strong>一本你启发小弟的代言人。</p>
<p><strong>《The Art of Unix Programming --UNIX编程艺术》</strong><br />
<img alt="" src="http://ec2.images-amazon.com/images/P/0735619670.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/0735619670.01._BO2,204,203,200_PIsitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com.cn/book/BookImage/lastTS0090969__.jpg" temp_src="http://www.dearbook.com.cn/book/BookImage/lastTS0090969__.jpg" />&nbsp;<br />
<br />
<img alt="" src="http://ec2.images-amazon.com/images/P/020161622X.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec2.images-amazon.com/images/P/020161622X.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com.cn/book/BookImage/47/lastTS0090353__.jpg" temp_src="http://www.dearbook.com.cn/book/BookImage/47/lastTS0090353__.jpg" />&nbsp;<br />
<img alt="" src="http://ec1.images-amazon.com/images/P/0131429019.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" temp_src="http://ec1.images-amazon.com/images/P/0131429019.01._BO2,204,203,200_PIlitb-dp-500-arrow,TopRight,45,-64_OU01_AA240_SH20_SCLZZZZZZZ_.jpg" /><img alt="" src="http://www.dearbook.com.cn/book/BookImage/lastTS0091589__.jpg" temp_src="http://www.dearbook.com.cn/book/BookImage/lastTS0091589__.jpg" /></p>
<h2>&nbsp;</h2>
<h2>五、高效读书心得</h2>
<p>&nbsp;&nbsp; 刚好Head
First系列开头都有一段教人如何读书的话，再加工整理如下：<br />
<br />
<strong>1.尽量阅读中文版</strong><br />
&nbsp;
虽然有人英文很强，有的翻译很差，但AnyWay 中文阅读与理解的时间，略读与快速定位的速度还是要快一些。<br />
&nbsp;
<br />
<strong>2.即时批注、总结笔记与交流</strong><br />
&nbsp;
虽然爱书，但发现最有效的读书方式还是不断的制造脂批本，读书时在重要的文字下划线，把自己的心得写在页旁。<br />
&nbsp;
在明天复习一次批注，最好可以有空重新整理笔记，或者拿来与人讨论。&nbsp;<br />
&nbsp;<br />
<strong>3.大量思考或重复记忆</strong><br />
&nbsp;
看书最郁闷的事情就是看完之后脑袋空空了。技术书还好点，虽然看的时候可能很辛苦，但就像学会了骑单车，之后再骑的时候总是会的；而偏设计与管理的书，最容易的事情就是看的时候很快，看完没什么留下到实践中。<br />
&nbsp;
所以，我们不能以看小说的速度来看设计书，要寻找思考的机会，思考是最好的记忆。<br />
&nbsp; 又或者，大量的重复记忆，重复多遍直到无意识的记忆。&nbsp;<br />
&nbsp;
<br />
<strong>4.人体工学</strong><br />
&nbsp;&nbsp;那些见缝插针的时间与地点不是看这个书单的好地方。<br />
&nbsp;
环境不要有电视，音乐等强输入源，而微风阳光鸟语等弱输入源则有助活跃大脑。<br />
&nbsp; 看书时大量的喝水。<br />
&nbsp;
如果发现自己的大脑已经疲累，已经在浮光掠影的翻看，就要休息。<br />
&nbsp; 留给大脑消化的时间，看完书不要接着看其他有难度的书或事情。</p>
<img src ="http://www.blogjava.net/bill2004158/aggbug/172034.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/bill2004158/" target="_blank">Bill Wang</a> 2008-01-01 23:32 <a href="http://www.blogjava.net/bill2004158/articles/172034.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>