本文最初发表在IEEE软件杂志上,IEEE软件杂志致力于发表严谨的、经过互相审校的文章,专注于当今世界的战略科技。为了满足运行可靠且灵活企业所面临的挑战,IT经理和技术管理者依赖IT Pro获取最先进的解决方案。
\\\\软件密集型的系统经常会因为各种各样的原因而必须进行重新设计,例如某个不可预知的业务变动或是技术上的创新。许多重新设计活动会对这些系统的软件架构产生影响,代码重构就是一种流行的重新设计实践。考虑到代码成功这一实践的巨大成功,这使人们对于架构重构(AR)这种实践的沉默感到有些吃惊。为了纠正这一情形,我将在本文中为读者展示,作为一种软件进化技术,AR如何重新审视架构决策,并确认相关的设计、实现及文档任务。
\\介绍架构重构
\\重构的目的是在改善某部分质量的同时保持其它部分不变,举例来说,代码重构实践对代码的结构进行了重新调整,以增强代码的可维护性,同时又保持它的可观察行为不变。代码重构实践是与机器可读的实体进行打交道,例如包、类以及方法,让这些实体能够在编译器构造阶段利用各种数据结构,例如抽象语法树1。而AR则是与架构文档和架构知识在代码与运行时产品中所表现出的行为打交道。因此,不存在一种单一的架构语法树。AR的范畴包括:
\\- 组件与连接器(经过建模、描绘或在代码中隐式地表现出来),\\t
- 设计决策的记录(以结构化和非结构化的文本表现),以及\\t
- 计划阶段的产物,例如项目管理工具中的工作项。\
AR能够找出架构中的坏味道,这种坏味道暗示着架构中的某部分对于目前的需求与约定来说已经不再适用,而这些需求比起从前可能已经产生了某种变化。从这一层意义上说,AR是一种将经过深思熟虑的架构活动进行整理后的集合,它能够去除某种特定的架构坏味道,能够在不影响系统的范围与功能的情况下,对系统中至少一方面的质量特性加以改进。而由于矛盾的需求与权衡因素的存在,AR也可能会对其它质量特性带来负面的影响。
\\在我看来,AR的过程就是对某个架构决策进行重新审视2,并为某些设计问题的集合提供一种不同的解决方案。决策的执行牵涉到多个相关的工程任务,它们可以被归类为以下几种:
\\- 认识到某个设计中的结构性变化的任务。这种变化的范围比起代码重构更大,它需要与组件、子系统以及系统的系统(和它们的接口)打交道。\\t
- 在开发与运维过程中的实现与配置任务(取决于AR的视角)。\\t
- 文档与交流任务,例如建模活动、技术写作工作、或技术研讨会的准备与促进。\
\\t\t\t AR名称 \\\t\t\t\\\t\t\t如何能够轻易地认出某个AR并进行引用? \\t\t\t | \\t\t\t SQL \\t\t\t |
\\t\t\t 背景 \\\t\t\t\\\t\t\t该AR适用于的场景(以及所处的条件)是什么? \\t\t\t | \\t\t\t 从功能性的观点与信息的观点这两者的角度对概念级别(数据库范式)以及资产级别(MySQL与MongoDB)进行抽象。 \\t\t\t |
\\t\t\t 项目干系人的关注点 \\\t\t\t\\\t\t\t该AR会影响到哪些非功能性需求以及约束(包括质量特性及设计外力)? \\t\t\t | \\t\t\t 灵活性(从数据模型变更的角度)、数据完整性,以及迁移时间。 \\t\t\t |
\\t\t\t 架构坏味道 \\\t\t\t\\\t\t\t在何时,以及为什么要考虑该AR? \\t\t\t | \\t\t\t 当数据模型(数据库架构)产生变动时,将现有的数据库内容进行迁移所需的时间太长。 \\t\t\t |
\\t\t\t 需要重新审视的架构决策 \\\t\t\t与该AR相关的设计问题有哪些,目前采取了哪些设计方式以处理这些问题? \\t\t\t | \\t\t\t
|
\\t\t\t 改进轮廓 (解决方案的简介) \\\t\t\t现在应当选择哪些设计选项? \\\t\t\t解决方案的目标看起来是怎样的? \\t\t\t | \\t\t\t
|
\\t\t\t 受影响的架构元素 \\\t\t\t哪些设计模型元素必须进行改动(例如被显式建模的组件与连接器)? \\t\t\t | \\t\t\t
|
\\t\t\t 执行任务 \\\t\t\t如何应用并验证该AR? \\t\t\t | \\t\t\t
|
表1. 某个架构重构(AR)的结构化表现。
\\我所设计的以决策和任务为中心的AR视图是对Michael Stal的观点的一种补充与扩展,他在2007年发表了关于AR的第一份目录3。为了对他的AR进行文档化,Stal使用了一种简单的模式格式,其中包括三个部分:背景、问题与一般方案意见。他所描述的AR包括“打破依赖循环”以及“切分子系统”,分别对应了“依赖循环”与“功能切分不充分”这两种架构上的坏味道4。
\\以任务为中心的模板的示例
\\Doodle.com的首席技术官在他们的博客上解释了他们为什么要从MySQL迁移到MongoDB的原因,这是在他们的协作型在线日程设定服务上线使用多年后所做出的一个决定。在这个案例中的架构坏味道在于,一旦SQL架构产生变化(例如在某张表中加入新的一列),对大型的生产环境中的数据库进行迁移的过程耗时极长。受到影响的质量特性包括开发与运维的生产力,以及数据库和数据访问层的性能与可伸缩性。而这种坏味道的症结在于,关系型数据库管理系统本身就不是为了应对这种使用场景而设计的,虽然它们能够勉强处理这种需求,但并非最佳选择。
\\他们所采用的方案是对架构方面的决策进行重新审视,这些决策包括数据库范式、查询API以及数据库provider。技术官最终决定使用面向文档的范式,这也是无架构的NoSQL技术中的其中一种,并使用MongoDB作为文档数据库的实现。这一变化改进了迁移管理的同时,也带来了管理与代码方面的成本,他们需要为此编写新的数据访问、事务以及备份管理方面的新方案。
\\Doodle的示例体现了一次成功的AR,因为它通过对某个架构决策进行重新审视,改善了某方面的质量特性,而并不包括代码的重构。表1以结构化的方式展现了这个AR过程,使它更容易理解,并能够应用到类似的项目中。这一示例也提供了一个AR文档模板的建议,表1中的每一行都是模板中的一个条目。图1展示了模板结构的结果。
\\在使用表1中展现的模板对你自己的AR进行文档化时,要注意AR名称应当具有表达性,例如某种隐喻。与通常使用名词的模式名称不同,AR名称应当是动词,例如在代码重构过程中所使用的名称。背景部分可以包含软件工程方法中的抽象级别信息,或者是企业架构管理框架中的观点。由于AR描述了一种设计上的变化,因此可以提供两种方案的简介,即应用AR前的设计以及应用AR之后的设计。架构元素与结构化设计之间建立了一种链接,这种链接可以被显式地建模、非正式的描述或在代码中进行隐式的表述。任务描述这部分可以引述敏捷计划工具或软件工程活动中的工作项。某些执行任务是可以被自动化的(正如在许多代码重构过程中的执行一样),但并非所有任务都可以,因为AR是在一个更高的抽象层面的过程,它的范围已超过了代码重构。
\\ \\图1. 某个架构重构的解剖图。左边的部分展示了在某个特定上下文(例如视角或抽象级别)中观察到的架构坏味道,这属于某种质量特性(QA)方面的关注点。右边的部分简述了经过重构后的架构,并确认了相关的设计、实现以及文档任务。而需要重新审视的架构决策而扮演了这两部分之间的粘合剂。
\\架构重构目录
\\让我们将目光放远一点,来看看一些其它的AR。表2以两个维度列举了基本的AR,分别是架构的角度与变更的类型。这些AR可以被表示为图1中的以任务为中心的模板实例。举例来说,“引入缓存”这一任务的具体工作包括决定一个查找键、缓存失效策略、缓存的分布等等。
\\在今后,还有可能出现特定于某个领域与风格的AR目录,可能会用于金融服务软件、游戏开发或云计算。举例来说,对于企业的应用现代化,以下三种AR都可以属于这一目录。
\\将会话状态管理功能转移(例如,从客户端或中间服务器转移至数据库,以改善水平伸缩的能力,并更好地利用云的弹性)。
\\- 在某个服务接口契约中,使用数据迁移对象取代标量参数(以减少远程调用的次数)。\\t
- 简化某个Web客户端(以减少客户端的负荷,增加它的处理能力)。\\t
- 基本的AR与特定的AR都能够提供一种跨社区的协作方式,协作双方可以包括:\\t
- 架构与开发。AR的执行可能会包括一次或多次代码重构的实践,这部分工作也必须统一规划。\\t
- 架构与项目管理。根据AR模板所组织的AR描述可以作为计划中的任务,对于AR的需求就意味着某种技术债的现形。\\t
- 架构与运维(ArchOps)。从部署的角度来看,可以将AR视为一种沟通的方式。\
表2. 视角、AR类型,以及对应的AR。
\\如何高效地共享并执行AR,这一点还有待观察。模板与目录是否能够有效地承载这些知识,还是说建模与协作工具更适合于这一场景呢?基于Web交付的知识具有天然的竞争力,这已经通过Wikipedia得到了证明。代码重构任务可以通过阅读书籍及正式的基础着手,而重构工具(例如Eclipse中的工具)是在很久之后才开发出来的,此时已经存在了丰富的内容,建立了完整的理论,人们也获得了大量的经验。对于AR工具的支持同样需要与建模工具相配合,这些建模工具能够支持UML或架构描述语言,但这种支持能力目前还没有看到。
\\致谢
\\感谢来自拉珀斯维尔的东瑞士应用科学大学的Christian Bisig与Mirko Stocker,他们对本文的原始版本进行了审校。同样感谢曾出席我在OOP 2014与GI FG SWA 2014会议上的演讲的听众,在演讲中我介绍了对云服务进行架构重构的方式,他们的反馈对我帮助很大。
\\引用
\\- M. Fowler于2004年9月1日所发表的博文“重构的定义”(Definition of Refactoring)。\\t
- O. Zimmermann于IEEE Software杂志2011年第28期第一卷中的64-69页中的文章,“将架构决策视为可重用的设计资产” (Architectural Decisions as Reusable Design Assets)。\\t
- M. Stal于2007年发表的“软件架构重构”(Software Architecture Refactoring)。\\t
- M. Stal与M. Babar、A. Brown、I. Mistrik、Morgan Kaufmann于2013年于敏捷软件架构第一期所发表的“重构软件架构”(Refactoring Software Architecture)。\\t
- P. Sevinç于2011年4月14日所发表的博文“Doodle技术面面观” (Doodle’s Technology Landscape)。\
关于作者
\\Olaf Zimmermann是拉珀斯维尔的东瑞士应用科学大学软件协会的一名教授与合作伙伴,可以通过ozimmerm@hsr.ch联系他。
\\\\本文最初发表在IEEE软件杂志上,IEEE软件杂志致力于发表严谨的、经过互相审校的文章,专注于当今世界的战略科技。为了满足运行可靠且灵活企业所面临的挑战,IT经理和技术管理者依赖IT Pro获取最先进的解决方案。
\\\\查看英文原文:Architectural Refactoring: A Task-Centric View on Software Evolution