架构设计的可视化建模
软件架构设计的难度源于软件设计问题本身的复杂性,一个复杂的软件系统往往存在大量复杂的、难于被人类所理解的细节和不确定因素。抽象与建模是人类自诞生以来就已掌握的理解复杂事物的方法,因而人类所从事的软件设计工作本质上也是一个不断建模的过程。我们可以通过各种抽象的模型和视图,从各个不同层次、宏观和微观的角度来理解复杂的软件架构,以保证作出正确和有效的设计。
有人认为:“软件架构就是源代码(source codes)”以及“源代码就是设计”。这种说法其实是片面的。什么是真正的软件?我们知道,最终可以在电脑上执行的真正的软件其实是二进制代码0和1,借助编译器我们把高级编程语言翻译成底层的汇编语言、机器语言等,没有人能直接、完整地看到二进制程序在CPU上的实际运行状况(runtime),人们大多只能通过各种调试工具、窗口视图等方式来间接地动态观察这些真正的软件的运行片段。因此,Java、C#、C++ 等等设计时(design time)源代码在本质上也是一种模型,虽然是一种经处理后可执行的静态模型,但显然它们并不是真实软件和软件架构的全部。可见,源代码模型(有时也叫实现模型)与UML模型其实都是软件架构的一种模型(逻辑反映),差别就在于抽象层次的不同。完整的软件架构(建筑)不仅仅包括源代码(实现模型),还包括了需求模型、分析模型、设计模型、实现模型和测试模型等等许多模型,软件架构本身就是一组模型的集合。
UML、SysML是当前国际上流行的软件/系统架构可视化建模语言。在编写实际的代码之前,利用包图、类图、活动图、交互图、状态图等等各种标准图形符号对软件架构进行建模,探讨和交流各种可行的设计方案,发现潜在的设计问题,保证具体编码实现之前抽象设计的正确性,被实践证明是一种非常有效和高效、敏捷的工作方式。
架构设计的重用
重用(Reuse)是在软件工程实践中获得高效率、高质量产品和系统开发的一种基本手段和主要途径,通过有组织的、系统和有效的重用,我们往往可以获得10倍率以上的效率提升。而一个优秀的、有长久生命力的软件架构(比方主流的一些框架软件),其本身或其组件被重用的次数越多,其体现的价值也就越大。
软件重用有各种不同的范围、层次、粒度和类型,从函数重用、类重用、构件/组件重用、库(API)重用,到框架重用、架构重用、模式重用,再到软件设计知识、思想的重用等等,重用的效能和效果各有不同。
软件工程经过几十年的发展,已经积累了大量的软件架构模式和设计模式,它们记载、蕴藏了大量成熟、已经验证的软件设计知识、思想和经验。我们平时对各种基础平台、主流框架和API的应用和调用,本身就是一种最为普遍的重用形式。而一个优秀、成熟的软件研发组织,必然会在日常开发中注意收集各种软件设计知识和经验,建立和维护基于架构模式和设计模式等内容的软件重用知识库,积极主动和频繁地运用各种软件模式来解决实际工程问题。
框架(Framework)是一类具有高可重用度的软件,针对某一类应用或领域,它们具有非常灵活的、高度可扩展的软件架构。那么,如何才能设计出可重用的软件架构或其组件?借助于OOA、OOD等抽象分析和设计技术是一种重要的方法。人们在实践中发现,往往越抽象的东西,其适应面也就越广,可重用度也就越高;相反,越具体的东西,其适应面也就越窄,可重用度也就越低。重用,意味着充分利用现成、既有的东西、成果来解决新问题或重复的问题,以“不变”应“万变”。在软件架构设计中,应该主动地区分软件架构中的“不变”与“可变”之处,系统地管理好这些稳定点和变化点以适应未来的变化,这也是提高软件架构重用度、获得高质量框架设计的一种重要方法。
架构设计的权衡
与其它所有工程行业一样,软件工程本质上也是一门讲究权衡的科学和艺术。软件架构设计的最难之处往往在于如何在各种相互竞争、矛盾的制约条件之下,作出巧妙的非常好的权衡。软件架构设计的权衡水平,也是最能体现软件架构师的设计经验、能力和技巧的地方。
在软件开发和软件架构的设计过程中,从选择平台,到选择语言,选择框架,选择设计模式,选择工具…等等,我们无时不刻都需要权衡,对各种候选项作出合理评判。在架构师带领下,软件研发团队往往还需要对近期目标与远期目标、质量与速度和效率、质量与成本、功能与性能、灵活性与复杂性…等等许多彼此矛盾的设计选项、因素和约束进行细致、小心和理性的权衡。
理性权衡意味着科学决策。进行有效的架构设计权衡,离不开科学的方法,也就是如何运用定量分析和定性分析相结合的方法、因果逻辑和根源分析等等技术,找到最终的甜点(Sweet Spot)。许多时候,能否在很短的时间内作出迅速、果断而正确的科学权衡与取舍决策,构成了一个软件研发团队核心竞争能力的一部分。