转 4+1视图方法的3大特点——4+1视图剖析系列

12年前
4+1视图方法的3大特点——4+1视图剖析系列

1995年,Philippe Kruchten在《IEEE Software》上发表了题为《The 4+1 View Model of Architecture》的论文,引起了业界的极大关注。

后来,Philippe Kruchten加入Rational,他的4+1视图方法演变为著名的、为许多架构师所熟知的“RUP 4+1视图方法”(如下图所示)。

概括而言:

  • 逻辑视图(Logical View),设计的对象模型。
  • 进程视图(Process View),捕捉设计的并发和同步特征。
  • 部署视图(Deployment View),描述了软件到硬件的映射,反映了分布式特性。
  • 实现视图(Implementation View),描述了在开发环境中软件的静态组织结构。
  • 用例视图(Use-Case View),该视图是其他视图的冗余(因此"+1")。

其实,就算不专门对比业界不同的多视图方法(本系列文章后续将谈及“业界种类繁多的多视图方法”),有经验的软件从业者也会感觉到4+1视图方法的3大特点扑面而来。

特点一,倚重OO

80年代到90年代OO技术是大有作为,例如许多人都知道C++是1985年横空出世的。4+1视图方法根植于Philippe Kruchten的一线架构设计实践,所以4+1视图方法倚重OO并不令人奇怪。

另一方面,几个问题很有价值:

  • 4+1视图方法,是OO方法的分支吗?
  • OO高手,就想当然的是架构师了吗?
  • 难道大量采用C语言编程的嵌入式领域不需要多视图?
  • ……

于是,在每个人的心里留下了一个大大的问号:OO方法 与 多视图的架构设计方法到底什么关系?

特点二,倚重用例

耐人寻味的“+1”。

Philippe Kruchten 4+1视图最初的“+1”,指场景视图(如下图)。RUP 4+1视图的“+1”,指用例视图(参考上图)。

用例技术不会和场景技术划等号吧?

4+1视图前后的“变迁”,为什么呢?(小沈阳味儿)

“逻辑视图”也叫“逻辑架构视图”也简称“逻辑架构”,但“用例架构”怎么这么别扭呢?

逻辑视图架构师负责设计,用例视图呢?

颇有影响的“用例驱动架构设计”的说法,如何评价?

一个个颇有价值的大问号不断出现,请朋友们先自己分析分析。分析时别忘了三把有用的钥匙:

  • 需求 = 功能 + 质量 + 约束
  • 用例是功能需求实际上的标准
  • 用例涉及、但不涵盖非功能需求

特点三,倚重建模

建模,很有用的能力。

但是,建模在架构设计中,到底占什么地位?凡事都需建模?

总结与展望

作为“4+1视图剖析系列”的开篇之作,本文提炼出4+1视图方法的3大特点。一则,对新手来说,便于建立总体印象,为理解后续内容做一下铺垫。二则,为后续的“剖析”埋下伏笔。

本质而言,先有实践,后有理论。再之后,就是“理论指导实践”、“实践促进理论”的绵绵无止的相互作用(多少有些类似“鸡和蛋”、“蛋和鸡”的绕绕关系)。

作为软件行业的从业者,若【不能从实践理解理论、不能将理论与实践融合】,会极大地限制个人发展。

《实践中的4+1视图方法》,上篇将较多关注“从实践理解理论”,下篇较多关注“将理论与实践融合”。

因为实践需要,所以多视图必要

架构设计就是对系统“切、切、切”,有人这么认为。

但是,和任何复杂的事物一样,随着了解慢慢加深,我们会发现一些比较深入的问题浮现出来。

我们虽已明了“架构设计应将系统切成不同部分”,但一旦开始深入实践,就会产生不少疑问:

  • 从用户角度而言,组成系统的是各种功能的模块,这属于架构设计的范围吗?(属于)
  • 对开发人员来说,他们认为系统是由不同的程序包组成的,架构设计师应不应该把这些统统丢给程序员决定呢?(不应该)
  • 更进一步而言,运行时系统又是由进程、线程等组成的,这属不属于架构设计的范围呢?(当然属于)

同样,我们虽已明了“架构设计应规定系统各部分之间如何交互”,但一旦开始深入实践,又困惑于:

  • 在用户看来,抽象的功能模块之间可以相互(直接或间接)调用功能服务,只有这样才能完成最终系统需要的业务功能,这是否属于架构设计的决策范围呢?(属于)
  • 程序类组成程序包,程序包组成程序系统,这些程序代码之间的调用等交互关系既有局部于包内的,也有跨包进行的,那么哪些属于架构师应该考虑的呢?(一般而言,某种级别的程序包之间的交互属于架构设计范围,这通常会采用定义接口的方式进行。不过,对于习惯把“接口属于客户”原则贯彻到代码结构设计中去的架构师而言,以及在进行框架开发的情况下,有可能出现接口定义在特定包比较密集的情况。)
  • 架构可以不关心进程或线程间的通讯和并发等问题吗?毕竟软件系统的性能和可伸缩性等问题于此息息相关啊。(应关心)

由此看来,由于软件架构概念是高度抽象的,所以在软件架构概念与实践之间,似乎存在某种“鸿沟”——即缺失某种概念,而这种概念可以连接软件架构的概念和实际的开发实践需要,为不同涉众理解和交流架构提供更专一的视角。这个概念就是:软件架构视图。

总结:因为实践需求,所以多视图必要。稍微“可视化”一点儿的概括应该是:

纯理论曰架构设计即切分<---->多视图<---->现实是架构设计涉及面广

4+1视图之父谈视图

那么,什么是软件架构视图呢?Philippe Kruchten在其著作《Rational统一过程引论》中写道:

一个架构视图是对于从某一视角或某一点上看到的系统所做的简化描述,描述中涵盖了系统的某一特定方面,而省略了于此方面无关的实体。

软件架构的每个视图分别关注不同的方面,针对不同的目标和用途。也就是说,架构要涵盖的内容和决策太多了,超过了人脑“一蹴而就”的能力范围,因此采用“分而治之”的办法从不同视角分别设计;同时,也为软件架构的理解、交流和归档提供了方便。

视图的另眼解读

来看一个生活中视图的例子。我们只有一个地球,但不同的时候我们会关心世界的不同问题:例如下图(世界人口分布图)是社会学家关心的,而气候学家则更关心下下图(世界年降水量分布图)。

世界人口分布图(图片来源:www.dlpd.com)

世界年降水量分布图(图片来源:www.dlpd.com)

其实上面就运用了“视图”作为手段,用不同的视图来刻画我们这个世界的不同方面。如果你喜欢,你完全可以将“世界人口分布图”称为“世界的人口分布视图”。这里引入视图的作用在于:世界地图的绘制者很难将不同的信息都绘制到同一幅图中;而看地图的人也希望有一幅地图是专门针对他的需要的。

而且,更进一步而言,同一事物的不同视图之间是有联系的。对比上面两幅图,除了南美洲之外基本都是降水量足的地方人口较密集——多好的例子呀!于是不难理解:软件架构的不同视图之间也存在相互影响。

4+1视图如何指导架构设计

因为实践需要,所以多视图必要。正如“纯理论曰架构设计即切分<---->多视图<---->现实是架构设计涉及面广”所总结的那样,4+1视图方法告诉我们【通过哪些视角、每个视角关注什么】,以此指导架构设计实践。

RUP 4+1视图的说法是:逻辑架构、实现架构、进程架构、部署架构。

Philippe Kruchten 4+1视图的说法是:逻辑架构、开发架构、进程架构、物理架构。

本“4+1视图剖析系列”沿用更普遍的说法:逻辑架构、开发架构、运行架构、物理架构。

逻辑架构。逻辑架构关注功能,不仅包括用户可见的功能,还包括为实现用户功能而必须提供的“辅助功能模块”;它们可能是逻辑层、功能模块、类等。

开发架构。开发架构关注程序包,不仅包括要编写的源程序,还包括可以直接使用的第三方SDK和现成框架、类库,以及开发的系统将运行于其上的系统软件或中间件。开发架构和逻辑架构之间可能存在一定的映射关系:比如逻辑架构中的逻辑层一般会映射到开发架构中的多个程序包;再比如开发架构中的源码文件可以包含逻辑架构中的一到多个类(在C++里一个源码文件可以包含多个类,即使在Java里一个源码文件也可以同时包含一个类和几个内部类)。

运行架构。运行架构关注进程、线程、对象等运行时概念,以及相关的并发、同步、通信等问题。运行架构和开发架构的关系:开发架构一般偏重程序包在编译时期的静态依赖关系,而这些程序运行起来之后会表现为对象、线程、进程,运行架构比较关注的是这些运行时单元的交互问题。

物理架构。物理架构关注“目标程序及其依赖的运行库和系统软件”最终如何安装或部署到物理机器,以及如何部署机器和网络来配合软件系统的可靠性、可伸缩性等要求。物理架构和运行架构的关系:运行架构特别关注目标程序的动态执行情况,而物理架构重视目标程序的静态位置问题;物理架构还要考虑软件系统和包括硬件在内的整个IT系统之间是如何相互影响的。

总结:一物看不清,就多角度看;多角度看一物,不同视角会相互影响。

4+1视图方法自1995年提出至今,极大地推动了架构领域的发展,但是,为什么架构设计一线仍是坏讯频传呢?原因之一恰在于“用”字。

人常说:手里只有一把锤子,看什么都像钉子。

我给企业做架构培训时又会专门补充强调:眼里没有钉子,手里的锤子又有什么用呢?

总之,作为一线架构师,【方法和问题的结合】才是实践之道。有方法,却不能真正结合软件一线的实际问题,则罔;有问题,却不能以最合理的方法予以真正解决,则殆;参透方法,吃透问题,并能合理运用,才叫“架构设计力”。熟悉王国维“三境界”说的朋友,看了下面一张培训幻灯片,会报以会心一笑吗?

多视图方法--------用于解决------->交流问题

第一个问题,软件架构的表达与交流问题。

这是个很现实的问题。究其原因,由于角色和分工不同,整个软件团队以及客户等涉众各自需要掌握的技术或技能存在很大差异,为了完成各自的工作,他们需要了解整套软件架构决策的不同子集。

所以,软件架构师应当提供不同的软件架构视图,以便于交流和传递设计思想。例如,负责部署和运营维护的系统工程师最关心软件系统基于何种操作系统之上、依赖于哪些软件中间件、有没有群集或备份等部署要求、驻留在不同机器上的软件部分之间的通信协议是什么等决策;而开发人员则最关心软件架构方案中关于模块划分的决定、模块之间的接口如何定义、甚至架构指定的开发技术和现成框架是不是最流行的等问题;……不一而足。

反过来,试想所有架构设计决策如果都混在一起表达会怎样?如此一来,不同的角色都会看到一个过于复杂的架构文档;更糟糕的是,谁都觉得难以理解这一软件架构,毕竟,将不同涉众关心的逻辑层(Layer)、物理层(Tier)、子系统、模块、接口、进程、线程、消息、协议等概念堆砌到一起,每个涉众都有可能看不懂了。

多视图方法--------用于解决------->思维问题

第二个问题,软件架构设计的问题。

这个问题更为关键。软件架构是个复杂的整体,架构师可以“一下子”把它想清楚吗?当然不能。有关思维的科学研究表明,越是复杂的问题越需要分而治之的思维方式。而每个软件架构视图关注软件架构不同的方面,使问题得以清晰化和简化,利于软件架构师完成架构设计工作。对此,Peter Herzum等人在《Business Component Factory》一书中就曾指出:

总的来说,“架构”一词涵盖了软件架构的所有方面,这些方面紧紧地缠绕在一起,决定如何将之分割成部分和主题显得相当主观。既然如此,就必须引入“架构视点”作为讨论、归档和理解大型系统架构的手段(Generally speaking, the term architecture can be seen as covering all aspects of a software architecture. All its aspects re deeply intertwined, and it is really a subjective decision to split it up in parts and subjects. Having said that, the usefulness of introducing architectural viewpoints is essential as a way of discussing, documenting, and mastering the architecture of large-scale systems.)。

软件架构设计中,会牵扯到很多概念和技术,例如逻辑层(Layer)、物理层(Tier)、子系统、模块、接口、进程、线程、消息、协议等等。而利于软件架构视图的方法,可以一次只围绕少数概念和技术展开,分别着重研究软件架构的不同方面。

必须强调

多重视图的软件架构不仅仅是架构归档的方式,更是架构设计的思维方法。

但是,笔者注意到,大多数书籍中都强调多视图方法是软件架构归档方法、描述方法(下图为某书目录),却忽视了该方法对架构设计思维的指导作用。

更多具体书籍我就不列举了,写Blog图个轻松交流,太累则不长远。

由于我职业特点的关系,大量接触一线的架构设计人员,我发现:“4+1视图 = 架构归档方法”这一观点已贻害无穷了。许多架构师甚至认为架构师就是个“建模和写文档的活儿”。所以必须引起注意!

从理论到实践:视图间同步

在运用5视图方法进行架构设计时需要注意两方面的问题,以适应实际情况的需要。

一个是多个架构视图之间的同步问题。

不同软件架构视图之间是独立的吗?不完全是。因为它们分别反映同一个软件系统的不同设计方面,它们最终合在一起才是完整的架构设计方案,所以不同架构视图之间势必有相互支撑的关系。所谓保持架构视图之间的同步,就是要保证不同视图之间是相互解释的、而不是相互矛盾的。

例如,逻辑架构中的一个逻辑层到了开发视图中可能变成了几个具体的程序包,而程序包编译(可能还包括打包)后的目标程序的部署(对嵌入式系统可能是烧写)是物理架构所要考虑的。再如物理架构中可能会涉及数据的分布和传递备份,这就需要数据架构中有相应数据的定义和结构信息等。

从理论到实践:视图的数量

另一个是架构视图的数量问题。

正如上面所讨论的,视图之间的同步是多视图方法的“开销”所在,因此一般而言,我们应该限制软件架构视图的数量。我们常常遇到的情况包括:

  • 有些软件系统并不涉及持久化数据,那么就不需要进行数据架构设计;
  • 运行于个人电脑之上的孤立的桌面应用,由于不涉及程序的分布问题,所有往往不需要单独的物理架构设计;
  • 对于业务逻辑较简单的软件(它们的计算逻辑未必简单),在实践中常常将逻辑视图和开发视图合二为一,此时“逻辑层”的概念可以和“程序包”的概念等同。

当然,如果需要,可以引入新的架构视图,从而更加突出和明确地制定和表达特定方面的架构决策。就拿安全性来说吧,如果安全性对软件系统来说极为关键,就可以引入单独的安全架构视图。在很大程度上,安全架构视图是其他视图中的安全性相关内容的汇集,例如:会话管理和授权管理等逻辑单元的引入来自逻辑视图;采用何种第三方加密算法包来自开发视图;消息的验证和转发涉及到运行视图;SSL等安全通信协议的使用策略来自物理视图;对数据库采用的专有安全限制策略来自数据视图。

总结

  • 项目不同角色观察软件架构的视角各不相同,每个视角涉及的需求和技术也不尽相同,所以将软件架构视图用作架构归档的手段是顺理成章的。
  • 软件架构视图可以被相对独立地分析和设计,这就使软件架构师可以暂时撇开其它问题、专注于特定问题进行深入的分析设计。
  • 是多个视图,不是多个架构。多个视图组成一个架构。
  • 视图数量由具体实践状况决定。