由 George Fairbanks 编著的《恰如其分的软件架构》一书致力于通过风险驱动的方法进行软件架构开发。
George 从多个视角阐述了架构建模过程,比如用例模型、概念模型、域模型、设计模型和代码模型。此外,他还探讨了多种架构风格,如大泥球模式(Big ball of mud)、管道过滤器模式(Pipe-and-filter)、Map-Reduce 模式,讨论了架构模式与架构风格之间的差异。这次采访还谈到了演化设计、架构重构以及如何对架构模型进行分析、测试和验证相关的话题。
十多年来,George 曾在 Kinetium、Valtech、和 Platinum Technology 等公司从事软件架构和面向对象的设计方面的教学工作。2008 年春天,他担任卡内基梅隆大学研究生软件架构课程的合作讲师;Georg 一直是软件体系结构工作会议 WISCA(Working International Conference on Software Architecture)、国际软件维护大 会 ICSM(International Conference on Software Maintenance)以及欧洲软件架构会议的委员会成员之一;此外,他还是 IEEE 软件工程汇刊和 IEEE 软件的仲裁委员。
InfoQ 就此书采访了 George,探讨了他的写作动机、他的论文项目——软件框架领域的设计片段,以及其他话题。此外,InfoQ 还为读者争取到了本书的书摘(第一章,简介;第三章:风险驱动的模型;第七章,软件架构的概念模型)
InfoQ:本书背后的主要写作动机是什么?
George Fairbanks:有两个方面。其一,转变架构就是摆在架子上的文档的错误观念。面向对象的设计和软件架构都是解决软件设计问题的方法——二者都是工程方法,是有助于开发者提高效率的工程技能。软件架构更多地关心设计问题并解决它们,而非编写的文档。
其二是想纠正一个误解——敏捷与架构水火不容。像许多常年混迹于电信行业中的开发人员一样,我所学习到的是,若实现一个电话交换,则一定要在 40 毫秒内发出拨号音,这是一个难以实现的需求。后来,我在金融界工作,又学习到建设一个缺乏安全的银行系统是行不通的。若你需要 50 毫秒才能发出拨号音,或者给坏蛋留下盗窃的机会,那么,任何其他特性都不再重要了。
并非每个项目都有一些让你寝食难安的失败风险。但是,当你的确碰到此类问题时——我的网站能否支持扩展到 100M 的点击率?我的投票系统安全吗?——你需要工程技术帮助你解决问题。往往会误认为这需要好几个月的时间才能解决,而实际上一个合适的架构设计可能仅仅需要几个小时或几天的时间。
InfoQ:你正在开展的一个论文项目叫做“软件框架领域的设计片段”。可否和我们谈一谈该项目,以及它对写作本书的影响吗?
George:有这么一个强有力的观点:框架是解决软件问题最佳方法。人们曾经抱怨在软件很难继续改善的同时硬件却正迎头赶上,可现在他们抱怨的是操作系统中有着太多的软件。通过框架,解决一个复杂的问题往往仅需几十行代码。可是,正如所有人都经历过的,问题是怎么找到这几十行代码,而这项工作却需要一整天的时间。
设计片段是一些模式,它们展示了客户代码如何插进框架之中。我开发了一个工具,它可用来浏览模式,将你的代码与它们绑定起来,用它来静态地检查你对模式的使用。这是一项在卡内基梅隆大学进行的论文研究项目,该项目是 David Garlan 和 Bill Scherlis 建议的,并与 Jonathan Aldrich 与 Ralph Johnson 组成委员会成员。
在今年的 OOPSLA/SPLASH 大会上,我碰到了 Ralph,他再次跟我提起他的建议。他回想起在自己曾努力普及重构和重构浏览器(refactoring browser,这是 Bill Opdyke 等人的论文)。他告诉我,问题不在于别人拿走了他的想法,而是人们忽略了这些想法!重构被 IDE 普遍接受花了 10 年的时间。我希望你这样的人能够继续探究设计片段,这样也许能使好想法不至于淹没在历史的大潮中。
InfoQ:在书中,您谈到将风险驱动的模型应用到敏捷流程。那么在实际工作中如何将架构相关的任务及工作引入敏捷软件开发过程之中,您有何建议?
George:书中描述的风险驱动的模型非常简单。你需将风险(风险是那些你担心可能会导致项目失败的事情,譬如容纳一百万并发用户或解决集成问题)按优先级排序,选择并应用架构方法来减低风险,然后判断这些风险是否已有应对。这个过程通常需要几个小时或几天的时间,而且很容易融入 2 周一次的功能交付的迭代周期。
但是,接受该想法的同时也意味着要抛弃一些别的想法。首先,架构意味着需要事先设计好一切。可是,在这里你只需探究并设计具有最大风险的部分。有时你需要对一些风险深入分析从而减少担忧,有时则不需要。
应抛弃的第二个想法是完备的架构描述。有时你的确需要一个完整的蓝图,而那通常是应为你正在开展一个巨大的项目,你需要和许多合作团队就设计进行探讨。那些有过这类经历的人应该已经知道这一点,因为你知道,最大的问题是组织结构(如何让 1000 个开发人员同心协力)问题,而非技术问题。而对其他项目而言,最好对一部分进行建模,比如只为服务器进行吞吐率模型,因为这是你最担心的风险。
通过抛弃 Big Design Up Front(译注:编码之前按照既定程序进行大量费时费力的设计工作)和完满的文档,就能方便地将架构融入那些有益的敏捷思想之中,譬如迭代开发、支持重构的测试套件和结对编程。
InfoQ:敏捷软件开发框架通过每日迭代总结、风险储备等方式已包含风险管理,该方法与您书中所介绍的风险驱动模型在管理软件架构方面有何差别?
George:乍一看,本书在风险管理问题上的建议可能与敏捷方法的建议有所不同,但是实际上它们探讨的是不同类型的风险。敏捷在降低项目管理风险上做的非常好,这些风险如构建了错误的程序包或交付延期。但对于工程风险,它大多依赖于开发者通过自己的技能解决。所以,如果你的项目需要成功地解决 UI、数据库或架构风险,开发者必须要掌握相应的技能。极限编程方法中没有关于该使用点对点架构或 3 层架构的建议。它为你扫除了许多管理上的风险,让开发人员可以专心地发挥他们疯狂的工程技能。
本书描述了一组架构技术,这些技术可使你成为更好的开发者。但是,如果你试图将它们全部应用起来,那就又回到了 Big Design Up Front,这不是个好主意。所以,本书推荐风险驱动模型,它指导你应用最有价值的架构技术,然后回到交付系统的工作之上。
敏捷,尤其是短迭代,可帮助你尽早发现问题。它可以使你的客户更早告诉你,你设计的 UI 不能用或者(间接地表明)数据库太慢。它所带来的益处同样适合于架构——能更早地发现 EJB 或 Hadoop 是否适用。
InfoQ:您在本书的第 14 章(架构风格)谈到了许多架构风格。在新兴的云计算世界里,应用程序(代码和数据)在外部系统中托管,对于这种架构转型,哪些架构风格和模式更适合呢?
George:有关架构风格,需要记住的最重要的一点是,它们就像“立刻能穿上身的胸衣”,能够帮助你的系统实现某方面的质量。譬如,管道过滤器网络可支持重配置、点对点系统在增加和删除节点时能保持运转、Map-reduce 可以跨多个廉价硬件进行并行计算。
书中有一个架构风格(或模式)目录,而且他们都能应用于托管计算环境,如云计算。租借硬件而非所有硬件可能会改变某些设计决定,但是对此进行报道仍为时尚早。
InfoQ:您认为特定域语言(DSL,Domain Specific Languages)可在软件架构的建模和执行中扮演什么角色?
George:学术界在定制架构语言领域的研究已有近 15 年了。这些语言,如 ACME、C2、AADL 和 SysML ,能够帮助你描述诸如组件、连接器和风格(它们不能直接通过 Java 表述)等架构概念。尽管我曾看过有些人使用 SysML 进行代码生成,但是它们大多用于建模。
然而,正如你说的,大多数人都已将 DSL 用于执行,尽管我们也许根本就没有想过这个问题。当你为 Struts 或 EJB 写配置文件,你就是在为系统定义拓扑。配置文件实际上是框架作者设计的 DSL 文件,开发人员用它来配置运行时系统。许多系统都遵循这种模式,在这些系统中,你编写一些模块 / 组件,然后通过一个外部配置文件定义他们之间的连接。
InfoQ:书中描述的模型如何用于管理企业内的安全体系架构(Security Architecture)的程序。
George:我不准备直接回答这个问题——Srini,你是安全体系结构方面的专家!那么,我要强调的是本书透露的一个信息:你的模型必须要根据问题进行裁剪。如果你建立一个模型来指定列车时刻表,你会使用当初用来计算火车折旧的模型吗?应该不会,对于软件也一样。如果你建立的模型对于预测用户请求的延时非常有效,它不一定能帮你发现安全漏洞。
工程师们长期以来一直在建立了很多模型。根据定义模型不包含所有细节。所以,为了在建模中浪费时间,首先应该明确你的模型要解决的问题,然后再建立一个模型来回答这个问题。
总的来说,软件开发者都是非常聪明的家伙。但是,交给我们的问题总是太大,所以单凭一个开发者的智慧是无法解决的。安全就是一个很好的例子: 我不相信有这样的开发者,他能从 1 千万行代码中发现所有的安全问题。可是,该系统的模型也许有所帮助。例如,系统的运行时视图就能方便地展现哪些服务可在防火墙外访问;或者,你也可以创建一个显示请求通路的定制视图,这样你就可以得知那些通道不对输入进行检测。模型是通过忽略细节、简化问题(将问题简化到能够装入一个人的大脑中并进行推理的粒度)的方式工作的。
InfoQ:对于本书以及软件架构(Software Architecture)的当前状态你还有什么想法和建议?
George:我很怀念 20 世纪 90 年代,不仅仅是因为当时的音乐很好听,另一原因是人们对软件设计的激情。当时的大会挤满了学习对象、设计模式和设计技术的开发者们。(还记得吗?)书店里摆满了关于最新软件设计思想的书籍。但是这些先进理念却受到官僚的企业软件开发流程的限制。最后,敏捷运动兴起啦!
今天,令人振奋的是敏捷开发。开发者们都致力于消除软件开发流程中的低效之处。他们转向短迭代,回归测试套件和结对编程。谢天谢地!他们似乎已经从之前的十年中学到了软件设计的经验教训,尽管,让我伤心的是,我的确碰到过一些并不懂得其设计模式的人。
笼统地说,每过十年软件就会增长 10 倍。所以,当我们关注解决流程问题时,我们的软件经历了一个数量级的增长。一点儿也不开玩笑,.NET 的文档比 《大英百科全书》还要厚。糟糕的设计带来的痛苦也成倍地放大了,所以,解决设计糟糕的 10M 行代码的系统中的问题比解决 1M 行代码的系统中的问题的复杂程度要超过 10 倍。而且你知道吗,明年软件又会变得更大!
我认为,此时我们应该将注意力转回设计。软件框架就像巨兽一样统治着地球,开发者们为生存挣扎着。因特网一级的系统及其非常吸引人的工程方法 (这些方法曾经只是少数几个 Bay Area 公司的突发奇想)已经成为家常便饭。我期待阅读有关这些新设计的书籍。
InfoQ:谢谢你参与这次 Q&A 形式的采访。最后一个问题,你最喜爱的技术和非技术书籍是什么?
George:在这里我就不再点名那些家喻户晓的经典书籍了,我要推荐的两本书是对我有很大影响但并非广泛传阅的书籍。其一是 Kent Beck 编著的《Smalltalk Best Practice Patterns》。他坐下来,反思他如何编写那些类、方法、和变量,好像在向我们展现那些描述其思维过程的一组模式一样,所以,读者在一定程度上能够走进Kent 编程过程中的思维。我的一个朋友开玩笑地说,Smalltalk 是导致这本书的销量低的原因,而且他准备将它重写成“Java Best Practice Patterns”,因为这些概念仍然适用。
第二本书是《Catalysis》,由Desmond D’Souza 与Alan Wills 合著。这本书的宏大和深度使得令人害怕,而且它所使用的精细的规范也吓走了许多读者。我现在写的不是那本书中的那些前置条件和后置条件,但是我发现,“思考”那些契约促使我编写更好的代码。那本书在软件设计问题上提出了很有用的建议,包括从方法到框架,乃至组件。
查看英文原文: Interview and Book Excerpt: George Fairbanks’ Just Enough Software Architecture
感谢吴宇对本文的审校。
给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家加入到 InfoQ 中文站用户讨论组中与我们的编辑和其他读者朋友交流。
评论