2009年上半年计算机技术与软件专业技术资格(水平)考试日期:2009年5月23、24日。
软件架构设计要点
如何更好地进行软件架构设计,这是软件工程领域中一个永恒的重点话题。过去几十年来,国际软件工程界在软件架构设计方面已经获得了长足发展,大量图书、文章和文献记载了这方面的成熟经验与成果。软件架构设计往往是一件非常复杂的工作,涉及到很多细节和方方面面,可探讨的话题也非常之多。囿于篇幅限制,以下只能根据笔者个人理解,遴选出软件架构设计的个别要点,结合当前流行的敏捷软件工程思想,与大家分享一下自己在软件架构设计方面的心得和体会。
架构决定成败
软件架构是软件产品、软件系统设计当中的主体结构和主要矛盾。任何软件都有架构,哪怕一段短小的HelloWorld程序。软件架构设计的成败决定了软件产品和系统研发的成败。软件架构自身所具有的属性和特点,决定了软件架构设计的复杂性和难度。
这几年流行一个说法(管理谚语):“细节决定成败”,这句话其实只说对了一半。细节确实很重要,很多项目、产品就输在细节的执行上。一方面,战术细节固然很重要,但另一方面,战略全局也同样重要,对应的我们可以说:“战略决定成败”。战略性失败,就好比下一盘围棋,局部下得再漂亮、再凌厉,如果罔顾大盘,己方连空都不够了,还有官子(细节)获胜的机会吗?必然是中盘告负。
类似地,正确的软件架构设计,应该既包括战略全局上的设计,也包括战术细节(关键路径)上的设计。有一种错误的观点认为,软件架构设计只要分分层和包,画一个大体的轮廓草图,就完事了。这种“纸上谈兵”型的架构师行为是非常有害的。事实上,既然软件架构是软件建筑的主体结构、隐蔽工程、承重墙和要害部位,那么软件架构也必然要落实到实际的算法和代码,不但要有实现代码,还要包括对这部分架构进行测试的代码,以保证获得高质量的、满足各种功能和非功能质量属性要求的架构。除了完成概念、模型设计外,软件架构师一定要参与实际的编码、测试和调试,做一位真正的hands-on practitioner,这已经成为了敏捷软件工程所倡导的主流文化。
两个架构
我们在日常的软件产品和系统开发中,实际上会遇到两种、两个部分的软件架构,即待开发的应用部分的软件架构(简称“应用架构”),以及既有的基础平台部分的软件架构(简称“基础架构”)。这两部分架构之间是互为依赖、相辅相成的关系,它们共同组成了整个软件产品和系统的架构。
基础架构的例子包括:.NET和J2EE等主流的基础平台和各种公共应用框架,由基础库API、对象模型、事件模型、各种开发和应用的扩展规则等内容组成。我们只有熟悉基础架构的构造细节、应用机理,才能有效地开发出高质量、高性能的上层应用。然而,开发一个面向最终用户的软件应用系统和产品,仅仅掌握一般的计算机高级编程语言知识和基础平台架构、API的使用知识显然是不够的,我们还需要根据客户应用的类型和特点,在基础架构之上,设计出符合用户要求的高质量应用软件。
熟悉OOA、OOD抽象建模技术、设计原则以及架构模式和设计模式等等方法技术,不但有助于我们更好地理解和利用基础平台架构,也有助于我们设计开发出更高质量的应用软件架构。
风险驱动、敏捷迭代的架构设计与开发
软件架构将随着软件产品和系统的生命周期而演化,其生命期往往超过了一个项目、一次发布,甚至有可能长达数年之久,因而软件架构无论对于客户还是开发商来说都是一项极其重要的资产。
软件架构的设计应该遵循什么样的开发过程?或者说,有没有更好的、成熟的软件架构设计和开发过程?回答是,21世纪的软件架构设计应该优先采用敏捷迭代的开发方式和方法。与传统做法不同,敏捷迭代开发主张软件架构采用演进式设计(evolutionary design),一个软件产品或系统的架构是通过多次迭代,乃至多次发布,在开发生命周期中逐步建立和完善起来的。
好的软件架构不是一蹴而就的。在架构设计开发过程中,我们应该尽量避免瀑布式思维,通过一个“架构设计阶段”来完成系统的架构设计乃至详细设计,然后再根据架构图纸和模型,在“编码实现阶段”按图索骥进行架构的编码与实现。这种传统做法的错误在于认为软件架构就是图纸上的模型,而不是真正可以高质量执行的源代码。几十年的软件工程实践表明,没有经过代码实现、测试、用户确认过的架构设计,往往会存在着不可靠的臆想、猜测和过度设计、过度工程,极易造成浪费和返工,导致较高的失败率。
风险是任何可能阻碍和导致软件产品/系统研发失败的潜在因素和问题。软件架构是软件产品和系统研发的主要矛盾和主要技术风险,软件架构的质量决定了整个软件系统和产品的质量。不确定性往往是软件架构设计当中一种最大的潜在风险。因此,软件架构的设计与开发应该遵循风险驱动的原则,在整个开发生命周期内至始至终维护一张风险问题清单,随着迭代的前进,根据风险的实时动态变化,首先化解和处理最主要的架构风险,再依次化解和处理次要的架构风险。
架构设计的可视化建模
软件架构设计的难度源于软件设计问题本身的复杂性,一个复杂的软件系统往往存在大量复杂的、难于被人类所理解的细节和不确定因素。抽象与建模是人类自诞生以来就已掌握的理解复杂事物的方法,因而人类所从事的软件设计工作本质上也是一个不断建模的过程。我们可以通过各种抽象的模型和视图,从各个不同层次、宏观和微观的角度来理解复杂的软件架构,以保证作出正确和有效的设计。
有人认为:“软件架构就是源代码(source codes)”以及“源代码就是设计”。这种说法其实是片面的。什么是真正的软件?我们知道,最终可以在电脑上执行的真正的软件其实是二进制代码0和1,借助编译器我们把高级编程语言翻译成底层的汇编语言、机器语言等,没有人能直接、完整地看到二进制程序在CPU上的实际运行状况(runtime),人们大多只能通过各种调试工具、窗口视图等方式来间接地动态观察这些真正的软件的运行片段。因此,Java、C#、C++ 等等设计时(design time)源代码在本质上也是一种模型,虽然是一种经处理后可执行的静态模型,但显然它们并不是真实软件和软件架构的全部。可见,源代码模型(有时也叫实现模型)与UML模型其实都是软件架构的一种模型(逻辑反映),差别就在于抽象层次的不同。完整的软件架构(建筑)不仅仅包括源代码(实现模型),还包括了需求模型、分析模型、设计模型、实现模型和测试模型等等许多模型,软件架构本身就是一组模型的集合。
UML、SysML是当前国际上流行的软件/系统架构可视化建模语言。在编写实际的代码之前,利用包图、类图、活动图、交互图、状态图等等各种标准图形符号对软件架构进行建模,探讨和交流各种可行的设计方案,发现潜在的设计问题,保证具体编码实现之前抽象设计的正确性,被实践证明是一种非常有效和高效、敏捷的工作方式。
架构设计的重用
重用(Reuse)是在软件工程实践中获得高效率、高质量产品和系统开发的一种基本手段和主要途径,通过有组织的、系统和有效的重用,我们往往可以获得 10倍率以上的效率提升。而一个优秀的、有长久生命力的软件架构(比方主流的一些框架软件),其本身或其组件被重用的次数越多,其体现的价值也就越大。
软件重用有各种不同的范围、层次、粒度和类型,从函数重用、类重用、构件/组件重用、库(API)重用,到框架重用、架构重用、模式重用,再到软件设计知识、思想的重用等等,重用的效能和效果各有不同。
软件工程经过几十年的发展,已经积累了大量的软件架构模式和设计模式,它们记载、蕴藏了大量成熟、已经验证的软件设计知识、思想和经验。我们平时对各种基础平台、主流框架和API的应用和调用,本身就是一种最为普遍的重用形式。而一个优秀、成熟的软件研发组织,必然会在日常开发中注意收集各种软件设计知识和经验,建立和维护基于架构模式和设计模式等内容的软件重用知识库,积极主动和频繁地运用各种软件模式来解决实际工程问题。
框架(Framework)是一类具有高可重用度的软件,针对某一类应用或领域,它们具有非常灵活的、高度可扩展的软件架构。那么,如何才能设计出可重用的软件架构或其组件?借助于OOA、OOD等抽象分析和设计技术是一种重要的方法。人们在实践中发现,往往越抽象的东西,其适应面也就越广,可重用度也就越高;相反,越具体的东西,其适应面也就越窄,可重用度也就越低。重用,意味着充分利用现成、既有的东西、成果来解决新问题或重复的问题,以“不变”应“ 万变”。在软件架构设计中,应该主动地区分软件架构中的“不变”与“可变”之处,系统地管理好这些稳定点和变化点以适应未来的变化,这也是提高软件架构重用度、获得高质量框架设计的一种重要方法。
架构设计的权衡
与其它所有工程行业一样,软件工程本质上也是一门讲究权衡的科学和艺术。软件架构设计的最难之处往往在于如何在各种相互竞争、矛盾的制约条件之下,作出巧妙的最佳权衡。软件架构设计的权衡水平,也是最能体现软件架构师的设计经验、能力和技巧的地方。
在软件开发和软件架构的设计过程中,从选择平台,到选择语言,选择框架,选择设计模式,选择工具…等等,我们无时不刻都需要权衡,对各种候选项作出合理评判。在架构师带领下,软件研发团队往往还需要对近期目标与远期目标、质量与速度和效率、质量与成本、功能与性能、灵活性与复杂性…等等许多彼此矛盾的设计选项、因素和约束进行细致、小心和理性的权衡。
理性权衡意味着科学决策。进行有效的架构设计权衡,离不开科学的方法,也就是如何运用定量分析和定性分析相结合的方法、因果逻辑和根源分析等等技术,找到最终的甜点(Sweet Spot)。许多时候,能否在很短的时间内作出迅速、果断而正确的科学权衡与取舍决策,构成了一个软件研发团队核心竞争能力的一部分。
架构设计的重要作用
要讨论软件架构设计在软件开发中的重要作用,首先让我们来了解一下目前国内软件的开发现状。
总的来说,国内的多数企业仍然是采用“瀑布模型”作为软件开发过程的主要模型。虽然在采用瀑布模型的同时可能会引入原型法以及诸如MSF等其它软件开发方法与过程,但随着项目时间的推进,这种“瀑布模型”会慢慢演化为“边做边改模型”。
从事过软件项目开发的专业人士都有这样的困惑:为什么到了项目接近尾声的时候,仍然还有那么多没有解决的问题?
理论上讲,应该是先分析,后设计,再编码,那为什么项目在交货以后,我们还在不断的编写设计文档?为什么每次客户需求发生变更,我们又要投入大量的资源来应对不断变化的客户需求?为什么软件开发会碰到这么多困难,我们天天加班加点,不断地去解决开发中碰到的种种问题,可是问题越解决越多,得到的效果却那么不尽人意?
项目出现这些问题,原因很多,概括起来可以分为两种:管理因素和技术因素。国内普遍重视管理因素,而忽视技术因素,所以出现层出不穷的问题也就无法避免。
软件架构设计属于技术因素,它位于软件开发过程的前期阶段,架构设计的过程,是分析客户需求、挖掘非功能性需求、并将客户需求所定义的领域知识转化为软件系统模型的过程,由此可见,架构设计所涵盖的范围非常广泛。
目前,国内对于软件架构的认识,还存在这样或那样的误区。难道只有当设计人员在为软件项目配备了充足的资源,然而却得不到预期的结果时,才会反思:是不是软件开发本身出现了问题?
架构设计源于客户需求
在进行需求分析的过程中,系统分析员将客户需求转化为计算机模型,然而在这个过程中,系统分析员本身的特性也就决定了这一角色很难把握住客户的非功能性需求。
需求需要挖掘,尤其对于大型的软件系统而言,光靠系统分析员这个单一的角色,很难完成需求分析与挖掘的艰巨任务。在需求分析的过程中,架构设计师更为关注的是系统的非功能性需求,例如稳定性、可扩展性、可维护性、安全性、高效性等等,这些需求都是需要挖掘的。
如何挖掘?挖掘方式取决于核心需求。举个很简单的例子,客户需要实现两个系统的数据传输,这是个核心功能性需求,而在这个需求的背后,还包括了“传输过程要求可靠”、“需要采用一种特定的数据格式进行传输”、“由于数据包含一定的机密因素,因此需要加密,并需要选择合适的加密算法”等等一系列的非功能性需求。
此时,架构设计师不仅需要了解客户本身的功能需求,还需要能够发掘非功能需求。因此,优秀的架构设计师一定是一个经验丰富的需求工程师,需求分析让架构设计师知道,我需要考虑哪些因素,而深厚的软件技术功底让架构设计师知道,如何去考虑这些因素。可见,架构设计源于客户需求。
架构设计源于对知识的不断积累
首先应该认识到,没有对领域知识、软件系统特性与软件技术等的深刻理解,就无从谈及架构设计,而深厚的领域知识与技术经验则是源于不断的积累。
目前,市场上确实很多产品在架构上已经非常成熟和稳定,但这些产品的成熟架构也是通过长期不断的实践与积累才逐步形成的。经验丰富的架构设计师可以在开发产品的同时总结出一套架构模式,这对维护产品的体系结构,以及开发同类产品都有深远的意义。
从另一个角度讲,产品的架构并非一成不变,随着技术的不断创新与发展,新技术一定会被应用到现有的系统架构中。此时,软件架构可能需要进行调整,我们也不能再说,我们没有必要去关心这些产品架构了。
架构设计是一种取舍过程
实现某一非功能性需求,可以有很多种方法,但并不是每种方法都是最合适的,这在架构设计的过程中需要做出取舍。例如,为了使得软件系统具有易扩展、易更改的能力,我们可以采用插件体系结构或内嵌脚本系统结构,两者都可以使得软件系统具有方便扩展的能力。
然而,如果客户的业务流程会经常变化,或者软件系统产品会应用到具有不同业务流程的多个客户时,采用后者可能会更加符合软件本身的特点。
当今IT业技术层出不穷,在特定的应用场景中,采用何种技术何种模式最合适,这就是架构设计的取舍。JAVA和.NET孰好孰坏?讨论这样的问题也不再有意义。软件工程大师Martin Fowler曾经说过:架构师是对所有重要事情做出决定的人,这一决定也囊括了取舍。
架构设计将服务于整个开发过程
良好的架构设计不仅使得软件系统能够满足客户需求,它更为软件系统带来了安全性、稳定性、可扩展性等属性,而这些属性在应对客户需求变更、提高软件可测试性与可维护性、降低维护成本、提高开发效率等各方面都起着非常重要的作用。
客户所需要的是可以用于生产实践的最终产品,他们自然不会去关心你的软件系统采用何种设计和架构,但作为软件系统的分析者、设计者和开发者,我们必须为软件产品寻求一种合理的架构设计,因为它不仅能够使系统满足非功能性需求,而且能够降低开发成本和维护费用。
总之,架构设计是软件开发过程的重要组成部分,它不是单纯的技术,也不具有一种特定的形式,更不是与客户需求无关的。良好的软件架构能够服务于整个开发过程,有效地降低项目风险,确保项目能够朝着健康的方向发展。因此,我们必须重视架构设计在软件开发中的重要作用。
3COME考试频道为您精心整理,希望对您有所帮助,更多信息在http://www.reader8.net/exam/