收藏 分销(赏)

如何开发一个软件的架构.doc

上传人:pc****0 文档编号:7169298 上传时间:2024-12-27 格式:DOC 页数:7 大小:47KB 下载积分:10 金币
下载 相关 举报
如何开发一个软件的架构.doc_第1页
第1页 / 共7页
如何开发一个软件的架构.doc_第2页
第2页 / 共7页


点击查看更多>>
资源描述
由于本书是关于软件构建的,因此本节不会告诉你如何开发一个软件的架构;它关注是如何确定一个业已存在的架构的质量。因为架构比需求离构建活动又近了一步,所以对架构的讨论也会比对需求的讨论更详细一些。 为什么要把架构作为前期准备呢?因为架构的质量决定了系统的“概念完整性”。后者继而决定了系统的最终质量。一个经过慎重考虑的架构为“从顶层到底层维护系统的概念完整性”提供了必备的结构和体系,它为程序员提供了指引——其细节程度与程序员的技能和手边的工作相配。它将工作分为几个部分,使多个开发者或者多个开发团队可以独立工作。 好的架构使得构建活动变得更容易。糟糕的架构则使构建活动几乎寸步难行。图3-7显示了糟糕的架构的另一个问题。 图3-7 离开了良好的软件架构,你可能瞄准了正确的问题,但却使用了错误的解决方案。也许完全不可能有成功的构建 在构建期间或者更晚的时候进行架构变更,代价也是高昂的。修复软件架构中的错误所需的时间与修复需求错误所需的时间处于同一数量级——即,多于修复编码错误所需的时间(Basili and Perricone 1984, Willis 1998)。架构变更如同需求变更一样,看起来一个很小的改动,影响也许是非常深远的。无论为了修正错误还是改进设计而引发架构变更,越早识别出变更越好。 Typical Architectural Components 架构的典型组成部分 很多组成部分是优秀的系统架构所共有的。如果你自己构建整个系统,那么在架构工作会与更详细的设计工作有重叠部分。在这种情况下,你至少应该思考架构的每个组成部分。如果你目前从事的系统的架构是别人做的,你应该能够不费力地找出其中重要的组成部分(无须戴上猎鹿帽、牵着猎犬、手拿放大镜)。在这两种情况中,你都需要考虑以下的架构组成部分。 Program Organization 程序组织 系统架构首先要以概括的形式对有关系统做一个综述。如果没有这种综述,要想将成千的局部图片(或十多个单独的类)拼成一幅完整的图画是相当伤脑筋的。如果系统是小小的只有12块的智力拼图玩具,你那一岁的小孩也能在眨眼功夫解决它。不过把12个子系统拼到一起要困难一些,而且如果你不能将它们拼起来,那么就无法理解你正在开发的那个类对系统有何贡献。 在架构中,你应该能发现对那些曾经考虑过的最终组织结构的替代方案的记叙,找到之所以选用最终的组织结构,而不用其他替代方案的理由。如果对某个类在系统中的角色没有一个清晰的构思,那么编写这个类就是一件令人灰心丧气的工作。描述其他组织结构,才能说明架构最后选定的这种系统组织结构的缘由,并且表明各个类都是慎重考虑过的。有一份对设计实践的综述发现,“维护‘设计的缘由’”至少与“维护设计本身”一样重要(Rombach 1990)。 架构应该定义程序的主要构造块(building blocks)。根据程序规模不同,各个构造块可能是单个类,也可能是由许多类组成的一个子系统。每个构造块无论是一个类还是一组协同工作的类和子程序,它们共同实现一种高层功能,诸如与用户交互、显示Web页面、解释命令、封装业务规则、访问数据,等等。每条列在需求中的功能特性(feature)都至少应该有一个构造块覆盖它。如果两个或多个构造块声称实现同一项功能,那么它们就应该相互配合而不会冲突。 应该明确定义各个构造块的责任。每个构造块应该负责某一个区域的事情,并且对其他构造块负责的区域知道得越少越好。通过使各个构造块对其他构造块的了解达到最小,你能将设计的信息局限于各个构造块之内。 应该明确定义每个构造块的通信规则。对于每个构造块,架构应该描述它能直接使用哪些构造块,能间接使用哪些构造块,不能使用哪些构造块。 Major Classes 主要的类 架构应该详细定义所用的主要的类。它应该指出每个主要的类的责任,以及该类如何与其他类交互。它应该包含对类的继承体系、状态转换、对象持久化等的描述。如果系统足够大,它应该描述如何将这些类组织成一个个子系统。 架构应该记述曾经考虑过的其他类设计方案,并给出选用当前的组织结构的理由。架构无须详细说明系统中的每一个类。瞄准80/20法则:对那些构成系统80%的行为的20%的类进行详细说明(Jacobsen, Booch, and Rumbaugh 1999; Kruchten 2000)。 Data Design 数据设计 架构应该描述所用到的主要文件和数据表的设计。它应该描述曾经考虑过的其他方案,并说明做出选择的理由。如果应用程序要维护一个客户ID的列表,而架构师决定使用顺序访问的列表(sequential-access list)来表示该ID表,那么文档就应该解释为什么顺序访问的列表比随机访问的列表(random-access list)、堆栈、散列表要好。在构建期间,这些信息让你能洞察架构师的思想。在维护阶段,这种洞察力是无价之宝。离开它,你就像看一部没有字幕的外语片。 数据通常只应该由一个子系统或一个类直接访问;例外的情况就是透过访问器类(access class)或访问器子程序(access routine)——以受控且抽象的方式——来访问数据。详细的解释请看第5.3节中的“隐藏秘密(信息隐藏)”。 架构应该详细定义所用数据库的高层组织结构和内容。架构应该解释为什么单个数据库比多个数据库要好(反之亦然),解释为什么不用平坦的文件而要用数据库,指出与其他访问同一数据的程序的可能交互方式,说明会创建哪些数据视图(view),等等。 Business Rules 业务规则 如果架构依赖于特定的业务规则,那么它就应该详细描述这些规则,并描述这些规则对系统设计的影响。例如,假定要求系统遵循这样一条业务规则:客户 信息过时的时间不能超过30秒。在此情况下,架构就应该描述这条规则对架构采用的“保持客户信息及时更新且同步”的方法的影响。 User Interface Design 用户界面设计 用户界面常常在需求阶段进行详细说明。如果没有,就应该在软件架构中进行详细说明。架构应该详细定义Web页面格式、GUI、命令行接口(command line interface)等的主要元素。精心设计的用户界面架构决定了最终做出来的是“人见人爱的程序”还是“没人爱用的程序”。 架构应该模块化,以便在替换为新用户界面时不影响业务规则和程序的输出部分。例如,架构应该使我们很容易地做到:砍掉交互式界面的类,插入一组命令行的类。这种替换能力常常很有用,尤其因为命令行界面便于单元级别和子系统级别的软件测试。 用户界面设计值得用整本书的篇幅来讨论,不过这超出了本书的范围。 Resource Management 资源管理 架构应该描述一份管理稀缺资源的计划。稀缺资源包括数据库连接、线程、句柄(handle)等。在内存受限的应用领域,如驱动程序开发和嵌入式系统中,内存管理是架构应该认真对待的另一个重要领域。架构应该估算在正常情况和极端情况下的资源使用量。在简单的情况下,估算数据应该说明:预期的实现环境(运行环境)有能力提供所需的资源。在更复杂的情况中,也许会要求应用程序更主动地管理其拥有的资源。如果是这样,那么“资源管理器/resource manager”应该和系统的其他部分一样进行认真的架构设计。 Security 安全性 架构应该描述实现设计层面和代码层面的安全性的方法。如果先前尚未建立威胁模型(threat model),那么就应该在架构阶段建立威胁模型。在制定编码规范的时候应该把安全性牢记在心,包括处理缓冲区的方法、处理非受信(untrudted)数据(用户输入的数据、cookies、配置数据(文件)和其他外部接口输入的数据)的规则、加密、错误消息的细致程度、保护内存中的秘密数据,以及其他事项。 Performance 性能 如果需要关注性能,就应该在需求中详细定义性能目标。性能目标可以包括资源的使用,这时,性能目标也应该详细定义资源(速度、内存、成本)之间的优先顺序。 架构应该提供估计的数据,并解释为什么架构师相信能达到性能目标。如果某些部分存在达不到性能目标的风险,那么架构也应该指出来。如果为了满足性能目标,需要在某些部分使用特定的算法或数据类型,架构也应该说清楚。架构中也可以包括各个类或各个对象的空间和时间预算。 Scalability 可伸缩性 可伸缩性是指系统增长以满足未来需求的能力。架构应该描述系统如何应对用户数量、服务器数量、网络节点数量、数据库记录数、数据库记录的长度、交易量等的增长。如果预计系统不会增长,而且可伸缩性不是问题,那么架构应该明确地列出这一假设。 Interoperability 互用性 如果预计这个系统会与其他软件或硬件共享数据或资源,架构应该描述如何完成这一任务。 Internationalization/Localization 国际化/本地化 “国际化”是一项“准备让程序支持多个locales(地域/文化)”的技术活动。国际化常常称为“I18n”,因为国际化的英文单词“Internationalization”首尾两个字符“I”和“N”之间一共有18个字母。“本地化/Localization”(称为“L10n”,理由同上)活动是翻译一个程序,以支持当地特定的语言的工作。 对交互系统,国际化问题值得在架构中关注。大多数交互式系统包含几十上百条提示、状态显示、帮助信息、错误信息,等等。应该估算这些字符串所用的资源。如果这是一个在商业中使用的程序,架构应该表现出已经考虑过典型的字符串问题和字符集问题,包括所用的字符集(ASCII、DBCS、EBCDIC、MBCS、Unicode、ISO 8859等),所用的字符串类型(C字符串、Visual Basic字符串等),如何无须更改代码就能维护这些字符串,如何将这些字符串翻译为另一种语言而又尽量不影响代码和用户界面。架构可以决定,在需要的时候,是在代码中直接嵌入字符串;还是将这些字符串封入某个类,并透过类的接口来使用它;或者将这些字符串存入资源文件。架构应该说明选用的是哪种方案,并解释其原因。 Input/Output 输入输出 输入输出(I/O)是架构中值得注意的另一个领域。架构应该详细定义读取策略(reading scheme)是先做(look-ahead)、后做(look-behind)还是即时做(just-in-time)。[qzy1] 而且应该描述在哪一层检测I/O错误:在字段、记录、流,或者文件的层次。 Error Processing 错误处理 错误处理已被证实为现代计算机科学中最棘手的问题之一,你不能武断地处理它。有人估计程序中高达90%的代码是用来处理异常情况、进行错误处理、或做簿记(housekeeping)工作,意味着只有10%的代码是用来处理常规的情况(Shaw in Bentley 1982)。既然这么多代码致力于处理错误,那么在架构中就应该清楚地说明一种“一致地处理错误”的策略。 错误处理常被视为是“代码约定层次/coding-convention-level”的事情——如果真有人注意它的话。但是因为错误处理牵连到整个系统,因此最好在架构层次上对待它。下面是一些需要考虑的问题。 ■ 错误处理是进行纠正还是仅仅进行检测?如果是纠正,程序可以尝试从错误中恢复过来。如果仅仅是检测,那么程序可以像“没有发生任何事”一样继续运行,也可以退出。无论哪一种情况,都应该通知用户说检测到一个错误。 ■ 错误检测是主动的还是被动的?系统可以主动地预测错误——例如,通过检查用户输入的有效性——也可以在不能避免错误的时候,被动地响应错误——例如,当用户输入的组合产生了一个数值溢出错误时。前者可以扫清障碍,后者可以清除混乱。同样,无论采用哪种方案,都与用户界面有影响。 ■ 程序如何传播错误?程序一旦检测到错误,它可以立刻丢弃引发该错误的数据;也可以把这个错误当成一个错误,并进入错误处理状态;或者可以等到所有处理完成,再通知用户说在某个地方发现了错误。 ■ 错误消息的处理有什么约定?如果架构没有详细定义一个一致的处理策略,那用户界面看起来就像“令人困惑的乱七八糟的抽象拼贴画”,由程序的不同部分的各种界面拼接而成。要避免这种外观体验,架构应该建立一套有关错误消息的约定。 ■ 如何处理异常(exceptions)?架构应该规定代码何时能够抛出异常,在什么地方捕获异常,如何记录(log)这些异常,以及如何在文档中描述异常,等等。 ■ 在程序中,在什么层次上处理错误?你可以在发现错误的地方处理,可以将错误传递到专门处理错误的类进行处理,或者沿着函数调用链往上传递错误。 ■ 每个类在验证其输入数据的有效性方面需要负何种责任?是每个类负责验证自己的数据的有效性,还是有一组类负责验证整个系统的数据的有效性?某个层次上的类是否能假设它接收的数据是干净的(clean,即,没有错误)? ■ 你是希望用运行环境中内建的错误处理机制,还是想建立自己的一套机制?事实上,运行环境所拥有的某种特定的错误处理方法,并不一定是符合你的需求的最佳方法。 Fault Tolerance 容错性 架构还应该详细定义所期望的容错种类。容错是增强系统可靠性的一组技术,包括检测错误;如果可能的话从错误中恢复;如果不能从错误中恢复,则包容其不利影响。 举个例子:为了计算某数的平方根,系统的容错策略有以下几种。 ■ 系统在检测到错误的时候退回去,再试一次。如果第一次的结果是错误的,那么系统可以退回到之前一切正常的时刻,然后从该点继续运行。 ■ 系统拥有一套辅助代码,以备在主代码出错的时候使用。在本例中,如果发现第一次的答案似乎有错,系统就切换到另一个计算平方根的子程序,以取而代之。 ■ 系统使用一种表决算法。它可以有三个计算平方根的类,每一个都使用不同的计算方法。每个类分别计算平方根,然后系统对结果进行比较。根据系统内建的容错机制的种类,系统可以以三个结果的均值、中值、或众数作为最终结果。 ■ 系统使用某个不会对系统其余部分产生危害的虚假值(phony value)代替这个错误的值。 其他容错方法包括,在遇到错误的时候,让系统转入某种“部分运转/partial operation”的状态,或者转入某种“功能退化/degraded functionality”的状态。系统可以自动关闭或重启。这些例子经过了必要的简化。容错是一个吸引人的复杂主题——可惜,它超出了本书的范围。
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 包罗万象 > 大杂烩

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服