二 架构设计中的方法学

我们可以了解到在图的背后隐藏着的需求:系统需要支持多种用户界面 , 包括为普通用户提供的HTML界面 , 为无线用户提供的WML界面 , 为管理员提供的Swing界面 , 以及为B2B业务设计的界面 。这是系统最重要的需求 , 因此 , 系统的设计者就需要确定一个稳定的架构 , 以解决多界面的问题 。相对于多界面的问题 , 后端的业务处理逻辑都是一致的 。比如HTML界面和WML界面的功能并没有太大的差别 。把处理逻辑和界面分离开来还有额外的好处 , 可以在添加功能的同时 , 不涉及界面的改动 , 反之亦然 。这就是我们在第二篇中提到的耦合度的问题 。
MVC模式正可以适用于解决该问题 。系统使用控制器来为业务逻辑选择不同的界面 , 这就完成了MVC架构的设计思路 。在架构设计的工作中 , 我们手头上有模式这样一张好牌 , 有什么理由不去使用它呢?
抓住重点
在架构设计一开始 , 我们就说架构是一种抽象 , 那就是说 , 架构设计摒弃了具体的细节 , 仅仅抓住软件最高层的概念 , 也就是最上层、优先级最高、风险最大的那部分需求 。
我们考虑、分析、解决一个问题 , 一定有一个渐进的过程 。架构设计就是解决问题其中比较早期的一个阶段 , 我们不会在架构设计这个阶段投入过多的时间(具体的原因在下文会有讨论) , 因此关键点在于我们要能够在架构设计中把握住需求的重点 。比如 , 我们在模式一节中提到了分布式系统和交互系统 , 分布和交互就是这两个系统的重点 。那么 , 如果说我们面对的是一个分布式的交互系统 , 那么 , 我们就需要把这两种特性做为重点来考虑 , 并以此为基础 , 设计架构 。而我们提到的宠物商店的范例也是类似的 , 除了MVC的架构 , 还有很多的设计问题需要解决 , 例如用于数据库访问的数据对象 , 用于视图管理的前端控制器 , 等等(具体使用到的架构模式可以访问sun的网站) 。但是这些相对于MVC模式来说 , 属于局部的 , 优先级较低的部分 , 可以在架构确定后再来设计 。
架构设计和领域专家
一个架构要设计的好 , 和对需求的理解是分不开的 。因此在现实中 , 我们发现业务领域专家凭借着他对业务领域的了解 , 能够帮助开发人员设计出优秀的架构来 。架构是需要抽象的 , 它是现实社会活动的一个基本模型 , 而业务领域的模型仅仅凭开发人员是很难设计出来的 。在ERP的发展史上 , 我们看到MRP发展为MRPII , 在发展到闭环MRP , 直到发展成为现在的ERP , 主要的因素是管理思想的演化 , 也就是说 , 对业务领域的理解进步了 , 架构才有可能进步 。
因此 , 敏捷型架构设计的过程中 , 我们也非常强调领域专家的作用 。
例3:信贷系统
在一个银行的信贷帐务处理系统中 , 我们应该如何把握最初的架构思路呢?从需求上来看 , 这个信贷帐务处理系统有几个特点:
它不是一个单独的系统 , 它需要和外部的其它系统交互 , 例如信贷业务系统、网上银行、数据仓库系统等 。
在所有的需求中 , 最复杂的就是它的利息计算的需求 , 它要求能够支持多种的利息算法 。
因此 , 我们的架构设计首先是从系统的全局环境开始考虑 。其它系统和该系统的关系如何 , 应该如何设计系统间的接口 。通过需求的调研 , 系统的接口分为4类:
和企业外部系统的接口 。信贷系统需要连接到人民银行的系统 。
和企业内部系统的接口 。信贷系统需要能够为数据仓库系统和网上银行系统提供数据 。
和平级系统的接口 。信贷系统需要从平级的帐户、资金、财务系统中取数据 , 并向帐户、押汇系统发送数据 。
具体的实现策略并不在我们的讨论范围之内 , 但是可以看到 , 架构策略的制定是以需求为基础的 。我们可以把这部分的需求归纳为技术架构或平台架构 。
然后是利息算法的问题 , 我们经过统计 , 目前的利息计算方式有四种 , 可预见到的还有两种 。在一开始的阶段 , 我们并不需要考虑具体算法的实现 , 但是我们需要考虑算法的实现框架 , 因此我们很自然的想到模式可以胜任这一工作 , 把不同的利息算法封装起来 。而我们的工作重点也就转到定义利息算法的接口问题 。通过分析、比较多种利息算法 , 我们定义了一个最初始的算法接口 , 然后由不同的利息算法来实现算法接口 。虽然 , 这个接口目前还不是很完整 , 但是它会在接下去的开发过程中慢慢的完善起来 。这部分的需求属于业务架构的一部分 。
考虑到系统的结构非常的复杂 , 因此在系统结构的处理上 , 我们采用了层模式做为系统的基本结构 。此外 , 在每个层 , 我们还定义了几个子模块来处理特定的问题 。这样 , 我们就可以将复杂的功能有序的组织起来 。
经过上述的分析 , 我们对系统的架构有了一个简单的认识 , 但是还没有结束 , 一个架构应该包括系统的各个基本部分 , 因此 , 我们还要考虑票据处理、报表、帐务处理等环节 , 但是一开始就考虑周详 , 这要花费大量的时间 , 因此我们只是简单的定义了一个原始的架构 , 然后在后续的开发过程中把这个架构完善起来
四、团队设计
团队设计是敏捷方法论中很重要的一项实践 。我们这里说的团队 , 指的并不是复数的人 。一群人就是一群人 , 并没有办法构成团队 。要想成为团队 , 有很多的工作要做 。
我们之所以考虑以团队为单位来考虑架构设计 , 是因为软件开发本身就不是一件个人的事情 , 架构设计更是如此 。单个人的思维不免有考虑欠妥之处 , 单个人的学识也不可能覆盖所有的学科 。而组织有效的团队却能够弥补这些缺憾 。
谁来负责架构的设计?
在我们的印象中 , 总认为架构设计是那些所谓架构设计师的专属工作 , 他们往往拥有丰富的设计经验和相关的技能 , 他们不用编写代码 , 就能够设计出理论上尽善尽美的架构 , 配有精美的图例 。
问题1:理论上设计近乎完美的架构缺乏程序的证明 , 在实际应用中往往会出这样那样的问题 。
问题2:设计师设计架构带有很大的主观性 , 往往会忽视客户的需求 , 导致架构无法满足需求 。
问题3:实现的程序员对这种架构有抵触的情绪 , 或是因为不理解架构而导致架构实现的失败 。
问题4:架构师设计架构主要是依据自己的大量经验 , 设计出的架构不能真实的反映目前的软件需要 。
团队设计的理论依据是群体决策 。和个人决策相比 , 群体决策的最大好处就是其结论要更加的完整 。而群体决策虽然有其优点 , 但其缺点也是很明显的:需要额外付出沟通成本、决策效率低、责任不明确、等等 。但是群体决策如果能够组织得当的话 , 是能够在架构设计中发挥很大的优势的 。
避免象牙塔式的架构设计
对软件来说 , 架构设计是一项至关重要的工作 。这样的工作交给某个人是非常危险的 。即便这个人再怎么聪明 , 他也可能会遗漏部分的细节 。组织有效的团队的力量是大大超过个人的力量的 , 因此团队的成果较之个人的成果 , 在稳定性和思考的周密程度上 , 都要更胜一筹 。
Scott W. 在其著作中给出了象牙塔式架构(ivory tower )的概念:
An ivory toweris one that is oftenby anorteam into the day-to-dayof yourteam(s).
中国现在的软件开发行业中也逐渐出现了象牙塔式的架构设计师 。这些架构师并不参与实际的程序编写 , 他的工作就是为项目制作出精美的架构模型 , 这种架构模型在理论上是相当完美的 。
例1:在XP中 , 我们基本上看不到架构设计的影子 。并不是说采用XP技术的团队就不需要架构设计 。XP不存在专门的设计时期 , 它提倡使用一些简单的图例、比喻的方式来表达软件的架构 , 而这种的架构设计是无时无刻不在进行的 。其实 , XP中的设计采用的就是团队设计的方式 , 结队编程(Pair )和代码的集体所有制( )是团队设计的基础 , 也就是基于口述的沟通方式 。通过采用这样的方式 , XP几乎不需要文档来表达架构的设计 。
优秀的架构师能够充分的利用现有框架 , 减少软件的投入 , 增强软件的稳定性 。这些都没有错 , 但是问题在于"过犹不及" 。象牙塔式架构师往往会出现文章开始指出的那些问题 。架构设计其实并不是非常复杂的工作 , 但它要求开发人员具备相关的技能、经验以及对问题域有一定的了解 。开发人员往往都具有相关的技术技能(编程、数据库设计、建模) , 而对问题域的理解可以从用户和行业专家那里获得帮助 。因此 , 在理论上 , 我们要实现架构设计的团队化是完全可能的 。

二  架构设计中的方法学

文章插图
在上面的象牙塔式架构定义中 , 我们看到架构师和日常的开发工作是隔绝的 。这样的设计出的架构有很大的局限性 。在现实中 , 我们还会发现另外一种角色 , 他来自于开发团队外部 , 为开发人员提供相关的技术或业务的培训 。这种角色称为教练 , 在软件开发中是非常重要的角色 , 不能够和象牙塔式架构设计师之间画等号 。
选择你的设计团队 。
软件的架构在软件的生命周期的全过程中都很重要 , 也就是说 , 软件开发团队中的所有人员都需要和架构打交道 。因此 , 最好的团队组织方式是所有开发人员都参与架构的设计 , 我们称这种方式为全员参与 。全员参与的方式保证了所有开发人员都能够对架构设计提出自己的见解 , 综合多方面的意见 , 在全体开发人员中达成一致 。这种方式尤其适合于一些小的团队 。
还是会有很多的团队由于种种的原因不适合采用全员参与的方式 。那么 , 组织优秀的开发人员组成设计组也是比较好的方式 。一般 , 我们选择那些在项目中比较重要的 , 有较多开发经验 , 或是理论扎实的那些人来组成设计组 。当然 , 如果你考虑到为组织培养后续力量 , 你也可以让一些新手加入设计组 , 或是你觉得自己的开发力量不足 , 邀请外部的咨询力量介入 , 这完全取决于具体的情况 。
设计组不同于我们之前提到的象牙塔式架构设计师 。设计组设计出来的架构只能称为原始架构 , 它是需要不断的反馈和改进的 。因此 , 在架构实现中 , 设计组的成员将会分布到开发团队的各个领域 , 把架构的思想带给所有开发人员 , 编写代码来检验架构 , 并获得具体的反馈 , 然后所有的成员再集中到设计组中讨论架构的演进 。
团队设计中存在的问题
在团队设计的过程 , 我们会遇到各种各样的问题 , 首当其冲的就是沟通成本的问题 。架构设计时 , 需求尚未被充分理解 , 软件的设计思路还处于萌发的状态 。这样的情况下 , 团队的每位成员对软件都有独特的见解 , 这些可能有些是相同的 , 有些是互斥的 。就好比盲人摸象一样 , 他们的观点都代表了软件的一部分或是一方面 , 但是没有办法代表软件的全部 。
在敏捷方法论中 , 我们的每一个流程都是迅速进行、不断改进的 。架构设计也是一样 , 我们不可能在一次架构设计上花费更多的时间 。而团队决策总是倾向于较长的讨论和权衡 。
例2中的问题在架构设计中时有发生 , 纯技术的讨论很容易上升称为争吵 。这种情况几乎没有办法完全避免 。团队型的决策必然会发生观念的冲突 。控制一定程度内的观念的冲突对团队的决策是有益 , 但是如果超出了这个程度就意味着失控了 , 需要团队领导者的调节 。而更重要的 , 我们需要注意沟通的技巧:
团队沟通
团队进行架构设计的时候沟通是一个非常需要注意的问题 , 上述的情境在软件组织中是经常发生的 , 因为技术人员很自然认为自己的技术比别人的好 , 如果自己的技术受到质疑 , 那怕对方是抱着讨论的态度 , 也无异于自身的权威受到了挑战 , 面子是无论如何都需要捍卫的 。而沟通如果带上了这样一层主观色彩 , 那么沟通信息的受众就会潜意识的拒绝接受信息 。相反 , 他会找出对方话语中的漏洞 , 准备进行反击 。因此 , 我们要注意培养一种良好的沟通氛围 。
在实际的观察中 , 我发现团队沟通中存在两种角色 , 一种是建议者 , 他们经常能够提出建议 。一种是质疑者 , 他们对建议提出否定性的看法 。这两种角色是可能互换的 , 现在的建议者可能就是刚才的质疑者 。质疑者的发言是很能打击建议者的积极性的 , 而在一个脑力激荡的会议中 , 最好是大家都能够扮演建议者的角色 , 这就要求沟通会议的主持者能够掌握好这一点 , 对建议给予肯定的评价 , 并鼓励大家提出新的建议 。
例2:敏捷方法非常注重的就是团队的沟通 。沟通是一个很有意思的话题 , 讲起来会花费大量的时间 , 我们这里只是针对架构设计中可能存在的沟通问题做一个简单的讨论 。我们这里假设一个讨论情境 , 这个情境来源于真实的生活:
项目主管徐辉、设计师李浩、设计师罗亦明正在讨论一个新的软件架构 。
"李浩你认为这个软件数据库连接部分应该如何考虑?"徐辉问 。
李浩想了想 , "我觉得方案A不错..." "方案A肯定有问题!这个软件和上一次的又不同 。"罗亦明打断了李浩的发言 。
"你懂什么!你到公司才多久 , 方案A是经过很长时间的证明的!"发言被打断 , 李浩有点恼火 , 罗亦明进入公司没有多久 , 但在一些事情上老是和他唱反调 。
"我进公司多久和方案A的错误有什么关系!"
在这样一种氛围中 , 会议的结果可想而知 。
良好的沟通有助于架构设计工作的开展 。一个成员的能力平平的团队 , 可以藉由良好的沟通 , 设计出优秀的架构 , 而一个拥有一个优秀成员的团队 , 如果缺乏沟通 , 最后可能连设计都出不来 。这种例子现实中可以找到很多 。
标准和风格
我们总是在不知不觉之中使用各种各样的标准和风格 。在团队设计中 , 我们为了提高决策的效率 , 可以考虑使用统一的标准和风格 。统一的标准和风格并不是一朝一夕形成的 。因为每个人都有自己不同的习惯和经历 , 强制性的要求开发人员使用统一的标准(风格)容易引起开发人员的不满 。因此在操作上需要注意技巧 。对架构设计而言 , 比较重要的标准(风格)包括以下的这些类别:
·界面设计
·流程设计
·建模规范
·编码规范
·持久层设计
·测试数据
在我的经验中 , 有一些组织平时并不注意标准(风格)的积累 , 认为这种积累属于雕虫小技 , 但正是这些小技 , 能够非常有效的提高沟通的效率和降低开发人员的学习曲线 。试想一下 , 如果一个团队中所有人写出的代码都是不同标准和风格的 , 那么理解起来肯定会困难许多 。当然 , 我们没有必要自己开发一套标准(风格)出来 , 现实中有很多可以直接借用的资料 。最好的标准是UML语言 , 我们可以从UML的官方网站下载到最新的规范 , 常用的编码标准更是随处可见 。不过虽然有了统一的标准 , 如果风格不统一 , 同样会造成沟通的障碍 。例如下图显示的类图 , 虽然它们表示的是同一个类 , 但是由于版型、可视性、详细程度的差别 , 看起来又很大的差别 。而在其它的标准中 , 这种差别也是普遍存在的 。因此 , 我们在使用了统一的标准之后 , 还应该使用同样的风格 。Scott W. 专门成立了一个网站讨论UML的建模风格的相关问题 , 有兴趣的读者可以做额外的阅读 。
图 4. 两种风格的类图
在统一的风格的基础上更进一步的是使用术语 。使用沟通双方都了解专门的术语 , 可以代表大量的信息 。最好的术语的范例就是设计模式的模式名 。如果沟通的双方都了解设计模式 , 那么一方只需要说这部分的设计可以使用工厂模式 , 另一方就能够理解 , 而不用再详细的解释设计的思路 。这种的沟通方式是最高效的 , 但它所需要的学习曲线也会比较陡 。
团队设计的四明确
为了最大程度的提高团队设计的高效性 , 可以从4个方面来考虑:
1、明确目标
泛泛的召开架构讨论会议是没有什么意义的 , 一个没有鲜明主题的会议也不会有什么结果 。在源自需求的模式中 , 我们谈到说可以有非功能需求的架构 , 可以有功能需求的架构 。因此 , 在进行团队设计之前 , 我们首先也需要确定 , 此次要解决什么问题 , 是讨论业务逻辑的架构 , 还是技术架构;是全局性的架构 , 还是各模块的架构 。
2、明确分工
我们之所以重视团队 , 很重要的额一个原因就是不同的成员有不同的擅长的区域 。有些成员可能擅长于业务逻辑的建模 , 有的擅长于原型设计 , 有的擅长于数据库设计 , 有的则擅长于Web编程 。你能够想象一个软件没有界面吗?(有些软件可能是这种情况)你能够想象一个软件只有数据库 , 而没有处理逻辑吗?因此 , 架构设计就需要综合的考虑各个方面 , 充分利用成员的优势 。这就要求团队的各个成员都能够明确自己的分工 。
3、明确责权
除了明确自己的分工 , 每位成员都需要清楚自己的责任 。没有责任 , 分工就不会有任何的效力 。每位成员都需要明确自己要做些什么 。当然 , 和责任相对的 , 没有成员还需要知道自己的权力是什么 。这些清楚了 , 进行高效的沟通的前提就具备了 。每次架构的讨论下来 , 每个人都清楚 , 自己要做些什么 , 自己需要要求其他人做些什么 , 自己该对谁负责 。如果这些问题回答不了 , 那这次的讨论就白费了 。
4、明确沟通方式
二  架构设计中的方法学

文章插图
这里使用沟通方式可能有一点点不恰当 , 为了明确的表达意思 , 大家可以考虑信息流这个词 。一个完整架构包括几个方面 , 分别都由那些人负责 , 如何产生 , 产生的整个过程应该是什么样的?这样的一个信息流程 , 囊括了上面提到的三个明确 。如果团队的每一个人都能够为架构的产生而努力 , 并顺利的设计出架构 , 那么这样的流程是完美的 。如果你发现其中的一些人不知道做些什么 , 那么 , 这就是流程出问题的现象了 。完美的流程还会有一个额外的副产品 , 架构产生之后 , 团队对于软件的设计已经是非常的清晰了 。因为我们提倡的是尽可能多的开发人员参与架构的设计 。
不仅仅是架构
讨论到这里 , 其实有很多的内容已经脱离了架构设计了 。也就是说 , 很多的原则和技巧都是可以用于软件开发的其它活动的 。至于哪一些活动能够利用这些方法呢?大家可以结合自己的实际情况 , 来思考这个问题 。提示一点 , 关键的入手处在于目前效率较低之处 。
我们说 , 和重型方法偏重于计划、过程和中间产物不同 , 敏捷方法更加看重人和沟通 。人和沟通永远是第一位的 , 而计划、过程和中间产物 , 那只是保证沟通、实现目标的手段 。这并不是说计划、过程、中间产物不重要 , 只是不能够本末倒置
注:我们把中间产物定义为为了实现跨边界的沟通而制定的文档、模型、代码 。例如设计文档、数据模型等 。参考RUP的 。
评判软件成功的标准有很多 , 对于敏捷方法论来说 , 成功的标准首先在于交付可用的软件 。为了保证软件的可用性 , 最重要的就是做好需求 。做好需求的方法有很多(参见拙作需求的实践) , 但这并不是我们讨论的主题 。对于我们要开始的架构设计的工作来说 , 从需求出发来设计架构 , 这就是保证软件可用性的一个基本的保证 。
我们如何开始我们的架构设计工作?
我们在进行架构设计的时候 , 往往主要考虑的都是平台、语言、开发环境、数据库等一些基本问题 , 可是对于和客户的具体情况密切相关的一些问题却很少系统的考虑 。甚至还存在一种误区 , 认为架构设计无非就是写一些空话 , 套话 。这样子做出来架构设计 , 如何用于指导软件的实现呢?
IT界的技术层出不穷 , 面对着如此之多的技术、平台、框架、函数库 , 我们如何选择一组适合软件的技术?
每一个客户的软件都有自身的特点 , 如何才能够设计出符合客户利益的架构?
软件中往往都充斥着众多的问题 , 在一开始就把所有的问题都想清楚往往很难做到 , 但是如果不解决问题 , 风险又居高不下 。
针对需求设计架构 。
架构设计就是铺设软件的主管道(例1) 。我们根据什么来制定主管道的粗细、路径等因素呢?很明显 , 是根据城市的人口、地理位置、水源等因素来决定的 。对应到软件设计也是一样的 。城市的各因素就是软件中的各种需求:功能需求、非功能需求、变化案例等等 。
一般来说 , 功能需求决定业务架构、非功能需求决定技术架构 , 变化案例决定架构的范围 。需求方面的知识告诉我们 , 功能需求定义了软件能够做些什么 。我们需要根据业务上的需求来设计业务架构 , 以使得未来的软件能够满足客户的需要 。非功能需求定义了一些性能、效率上的一些约束、规则 。而我们的技术架构要能够满足这些约束和规则 。变化案例是对未来可能发生的变化的一个估计 , 结合功能需求和非功能需求 , 我们就可以确定一个需求的范围 , 进而确定一个架构的范围 。
从例2中 , 我们看到自已字处理软件的几种需求的范例 。真正的字处理软件要复杂的多 。而我们最主要的就是必须认识到 , 架构是来自于需求的 。有什么样的需求就有什么样的架构 。试想一下 , 如果我们没有对速度的要求 , 我们还需要考虑这方面的设计吗?我们上面提到了几种类型的需求对架构的影响 , 其实还有一个很重要的需求 , 就是环境的需求 。这并不是一个很重要的需求 , 但是对于部署()架构设计来说就特别重要 。毕竟 , 我们开发出的软件是要上"战场"的 , 充分的考虑部署问题是非常有必要的 。
例1:城市中自来水管的架设是一项非常的复杂的工程 。为了需要满足每家每户的需要 , 自来水管组成了一个庞大的网络 。在这样一个复杂的网络中 , 如何完成铺设的任务呢 。一般的做法是 , 先找出问题的根源 , 也就是水的源头 。从水源铺设一条管道通至城市 , 然后根据城市的区域划分 , 设计出主管道 , 剩下的就是使用的问题了 , 每家每户的管道最终都是连到主管道上的 。因此 , 虽然自来水网络庞大复杂 。但是真正的主管道的非常简单的 。
例2:我们打算开发一个字处理软件 , 功能需求可以简单概括为格式化用户输入的文字 , 非功能需求可能是格式化大小为1000K的一段文字的处理速度不能低于10S , 变化案例可能是推出多种语言版本 。那么我们在设计业务架构的时候 , 我们会集中于如何表示文字、图象、媒体等要素 , 我们该需要有另外的技术架构来处理速度问题 , 比如缓冲技术 , 对于变化案例 , 我们也要考虑相应的架构 , 比如把字体独立于程序包的设计 。
从需求到架构 。
在需求阶段 , 我们可以得到一些代表需求调研成果的中间产物 。比如说 , CRC卡片、基本用例模型、用户素材、界面原型、界面原型流程图、非功能需求、变化案例等 。我们在架构设计阶段的主要工作就是要把这些需求阶段的中间产物转换为架构设计阶段的中间产物 。
图 3. 需求阶段的中间产物
其实 , 架构设计就是要完成两项工作 , 一是分析 , 二是设计 。分析是分析需求 , 设计则是设计软件的大致结构 。很多的方法论把分析和设计两种活动分开来 , 但其实这两者是很难区分的 , 做分析的时候会想到如何设计 , 而思考如何设计反过来又会影响分析的效果 。可以说 , 他们两者之间是相互联系和不断迭代的 。这种形态我们将会在后面的迭代设计模式中详细的讨论 。
在敏捷方法论中 , 需求最好是迭代进行的 , 也就是说一点一点的作需求 。这种做法在那些需求变化快的项目中尤其适用 。由于我们采用的流程是一种迭代式的流程 , 这里我们将会面临着如何对待上一次迭代的中间产物的问题 。如果我们每一次迭代都需要修改已存在的中间产物 , 那么这种维护的成本未免过大 。因此 , 敏捷方法论的基本做法是 , 扔掉那些已经没有用处的中间产物 。还记得在第一章的时候 , 我们强调说软件要比文档重要 。我们生成中间产物的目的都是为了生成最终的程序 , 对于这些已经完成作用的模型 , 没有必要付出额外的维护成本 。
不要断章取义的采用抛弃模型的做法 。因为 , 抛弃模型的做法需要一个适合环境的支持 。后面会针对这个话题开展大范围的讨论 。这里我们简单的做一个了解:
·简单化:简单的模型和简单的程序 。模型和程序越复杂 , 就需要更多的精力来处理它们 。因此 , 我们尽可能的简化它们 , 为的是更容易的处理它们 。
·高效的沟通渠道:通过增强沟通的效果来减少对中间产物的需要 。试想一下 , 如果我随时能够从客户那里得到需求的细节资料 , 那前期的需求调研就没有必要做的太细致 。
·角色的交叉轮换:开发人员之间建立起交换角色的机制 , 这样 , 能够尽量的避免各子系统诸侯割据的局面 。
·清晰的流程:或者我们可以称之为明确的过程 。过程在方法论中向来都是一个重点 , 敏捷方法论也不例外 。开发人员能够清楚的知道 , 今天做什么 , 明天做什么 。过程不是给别人看的 , 而是给自己用的 。
·工具:好用的工具能够节省大量的时间 , 这里的工具并不仅仅指CASE工具 , 还包括了版本控制工具、自动化测试工具、画图工具、文档制作和管理工具 。使用工具要注意成本和效益的问题 。
·标准和风格:语言不通是沟通的一个很大的障碍 。语言从某个角度来看属于一种标准、一种风格 。因此 , 一个团队如果采用同样的编码标准、文档标准、注释风格、制图风格 , 那么这个团队的沟通效率一定非常的高 。
如果上述的环境你都不具备 , 或是欠缺好几项 , 那你的文档的模型还是留着的好 。
仅针对需求设计架构
仅针对需求设计架构的含义就是说不要做未来才有用的事情 。有时候 , 我们会把架构考虑的非常复杂 , 主要的原因就是我们把很多未来的因素放入到现在来考虑 。或者 , 我们在开发第一个产品的时候就视图把它做成一个完美的框架 。以上的这两种思路有没有错呢?没有错 , 这只是如何看待投入的问题 , 有人希望开始的时候多投入一些 , 这样后续的投入就会节省下来 。但在现实中 , 由于需求的不确定性 , 希望通过增加开始阶段的投入来将降低未来的投入往往是难以做到的 , 框架的设计也绝对不是能够一蹴而就的 , 此这种做法并不是一个好的做法 。所以我们在后头会着重论述架构设计的简单性和迭代过程 , 也就是因为这个理由 。
模式
模式将可以帮助我们抓住重点 。设计模式在书的一开始(第二章)就讨论了一个设计一个文档编辑器的问题 。为了解决设计文档编辑器引出的七个问题 , 一共使用了8种不同的模式 。这8种模式的组合其实就是架构 , 因为它们解决的 , 都是系统中最高层的问题 。
在实践中 , 人们发现架构也是存在模式的 。比如 , 对于系统结构设计 , 我们使用层模式;对于分布式系统 , 我们使用代理模式;对于交互系统 , 我们使用MVC(模型-视图-控制器)模式 。模式本来就是针对特定问题的解 , 因此 , 针对需求的特点 , 我们也可以采用相应的模式来设计架构 。
在sun网站上提供的 宠物商店的范例中 , 就把MVC模式的思想扩展成为架构的思想 , 用于提供不同的界面视图:
【二架构设计中的方法学】MVC架构图 , 这里提供原图的概览 , 查看其出处请点击这里。