软件架构设计:程序员向架构师转型必备(第2版)(txt+pdf+epub+mobi电子书下载)


发布时间:2020-09-09 13:11:18

点击下载

作者:温昱

出版社:电子工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

软件架构设计:程序员向架构师转型必备(第2版)

软件架构设计:程序员向架构师转型必备(第2版)试读:

版权信息书名:软件架构设计:程序员向架构师转型必备(第2版)作者:温昱排版:追风筝的人出版社:电子工业出版社出版时间:2012-07-01ISBN:9787121170874本书由电子工业出版社授权北京当当科文电子商务有限公司制作与发行。— · 版权所有 侵权必究 · —第1部分基本概念篇第1章 从程序员到架构师

自由竞争越来越健全,真正拥有实力的人越来越受到推崇。……努力钻研,力求在更高水平上解决问题的专家不断增加,这正如电脑处理信息的能力在不断提高一般。如今,这样的时代正在到来。——大前研一,《专业主义》

机会牵引人才,人才牵引技术,技术牵引产品,产品牵引更大的机会。在这四种牵动力中,人才所掌握的知识处于最核心的地位。——张利华,《华为研发》

人才,以及合理的人才结构,是软件公司乃至软件业发展的关键。

成才,并在企业中承担重要职责,是个人职业发展的关键。1.1 软件业人才结构1.1.1 金字塔型,还是橄榄型?

有人说,软件业当前的人才结构是橄榄型(中间大两头小),需求量最大的“软件蓝领”短缺问题最为凸显,这极大地制约着软件业的发展,因此要花大力气培养大量的初级软件程序员等“蓝领工人”。

但业内更多人认为,软件业当前的人才结构是金字塔型,高手和专家型人才的总量不足才是“制约发展”的要害,因此一方面软件工程师应争取提升技能、升级转型,另一方面企业和产业应加强高级技能培训、高级人才培养。

软件业的人才结构,到底是金字塔型,还是橄榄型?

本书认为,一旦区分开“学历结构”和“能力结构”,问题就不言自明了(如图1-1所示):

· 学历结构=橄榄型。“中级学历”最多。有资料称,软件从业者中研究生、本科与专科的比例大致是1:7:2。

· 能力结构=金字塔型。“初级人才”最多。工作 3 年以上的软件工程师,就一跃成为“有经验的中级人才”了吗?显然不一定。

· 有学历 ≠ 有能力。每个开发者真正追求的是,成为软件业“人才能力结构”的顶级人才或中级人才。图1-1 人才结构的两个视角1.1.2 从程序员向架构师转型

人才能力的金字塔结构,注定了软件产业的竞争从根本上是人才的竞争。具体到软件企业而言,一个软企发展的好坏,极大地取决于如下人才因素:

· 员工素质。

· 人才结构。

· 员工职业技能的纵深积累。

· 员工职业技能的适时更新。

借用《华为研发》一书中的说法,“机会、人才、技术和产品是公司成长的主要牵动力。机会牵引人才,人才牵引技术,技术牵引产品,产品牵引更大的机会。在这四种牵动力中,人才所掌握的知识处于最核心的地位。”

然而,纯粹靠从外部“招人”,不现实。何况,软件企业、软企的竞争对手和软件产业环境,都处在动态发展之中。因此,软件企业应该:

· 定期分析和掌握本公司的员工能力状况、人才结构状况;

· 员工专项技能的渐进提升(例如架构技能、设计重构技能);

· 研发骨干整体技能的跨越转型(例如高级工程师向架构师、系统工程师和技术经理的转型)。

对于本书的主题“软件架构设计能力的提升”而言,架构设计能力是实践性很强的一系列技能,从事过几年开发工作是掌握架构设计各项技能的必要基础。因此可以说,“从程序员向架构师转型”不仅是软件开发者个人发展的道路之一,也是企业获得设计人才的合适途径。1.2 本书价值

本书包含3部分,分别是:

· 第1部分:基础概念篇。

· 第2部分:实践过程篇。

· 第3部分:模块划分专题。

读者可以根据自身发展状况、实际工作需要,选择合适的阅读路径(如图1-2所示)。图1-2 不同目的,不同阅读路径1.2.1 阅读路径1:架构设计入门

对于架构还未入门的程序员,推荐先重点阅读“基础概念篇”和“模块划分专题”:

· 基础概念篇解析架构概念(第 2 章)之后,讲解如何运用“逻辑视图+物理视图”设计架构(第3章)。

· 模块划分专题讲解模块划分的不同方法,将讨论功能模块、分层架构、用例驱动的模块划分过程等内容(第12~15章)。

架构设计入门必过“架构视图关”。本书细致讲解“逻辑视图+物理视图”的运用,如图 1-3所示,体会了“分而治之”和“迭代式设计”这两点关键思想,运用“逻辑视图+物理视图”设计一个系统的架构也就不那么难了。图1-3 两视图法的“分而治之”和“迭代”思想

架构设计入门必过“模块划分关”。本书“模块划分专题”总结了模块划分的 4 种方式,如图 1-4 所示。这其中,既有“水平分层”、“垂直划分功能模块”和“从用例到类、再到模块”等设计思想,也有不推荐的想到哪“切”到哪的设计方式。图1-4 业界模块划分的4种做法

当一个程序员,看懂了他们团队的架构师是如何划分模块的(甚至问“你为啥只垂直切子系统没分层呢”),那他离成为架构师还远吗?1.2.2 阅读路径2:领会大系统架构设计

入门之后,进一步学习大型系统架构成败的关键——概念架构设计。推荐精读如下两章:

· 第8章。如何确定影响架构设计的关键需求。

· 第9章。概念架构如何设计。

小系统和大系统的架构设计之不同,首先是“概念架构”上的不同,而归根溯源这是由于架构所支撑的“关键需求”不同造成的。整个架构设计过程中的“确定关键需求”这一环节,可谓小系统和大系统架构设计的“分水岭”,架构设计走向从此大不相同。

概念架构是直指系统目标的设计思想、重大选择,因而非常重要。《方案建议书》《技术白皮书》和市场彩页中,都有它的身影,以说明产品/项目/方案的技术优势。因此,也有人称它为“市场架构”。

概念架构设计什么?从设计任务上,概念架构要明确“1 个决定、4个选型”,如图1-5所示。图1-5 概念架构设计什么?

概念架构如何设计?从设计步骤的顺序上,本书推荐(如图1-6所示):

· 首先,选择架构风格、划分顶级子系统。这两项设计任务是相互影响、相辅相成的。

· 然后,开发技术选型、集成技术选型、二次开发技术选型。这三项设计任务紧密相关、同时进行。另外可能不需要集成支持,也可以决定不支持二次开发。图1-6 概念架构如何设计?1.2.3 阅读路径3:从需求到架构的全过程

专业的架构设计师,必须掌握架构设计的“工程化过程”。以此为目标的读者,请精读“实践过程篇”的内容。

· 第 4 章。概述从需求到架构的全过程,还提供了一节叫“速查手册”,供快速查阅每个环节的工作内容。

· 第5~11章。按如下6 个环节的展开讨论:需求分析、领域建模、确定关键需求、概念架构设计、细化架构设计、架构验证。

内容虽多,用一幅图概括也不是不可能,在为企业培训架构时我们就经常这么做——图 1-7即,展示了从需求到架构整个过程中的关键任务项。图1-7 架构设计的全过程1.2.4 阅读路径4:结合工作,解决实际问题

最后,按照经典名著《如何阅读一本书》中所说的“主动阅读”法,读者还可以“带着问题”、“以我为主”地“跳读”。【实际问题1】开发人员的一个很经典的困惑是:领域经验不足怎么办?

本书第7章,给出了建议。破解“领域知识不足”死结的一个有效方法,是把领域模型作为“理解领域的手段”。领域模型的“强项”是“理顺概念关系、搞清业务规则”——通过对复杂的领域进行“概念抽象”和“关系抽象”建立模型、获得对领域知识总体上的把握,就不会掉入杂乱无章的概念“堆”里了。【实际问题 2】又例如,你所在的部门,是否存在这样的问题:不同的人对架构有不同的理解?

本书第2章,推荐结合部门的实际工作,来理解架构的含义,统一团队不同成员对架构的理解。【实际问题3】用例建模够不够?流程建模要不要?笔者接触的很多实践者,都有此困惑。

本书第6章,简述了需求分析“三套实践论”的观点,提出“大、中、小”三套可根据系统特点选择的需求实践策略,可供实践者参考。如图1-8、图1-9和图1-10所示。图1-8 需求实践论之小型方法图1-9 需求分析实践论之中型方法图1-10 需求实践论之大型方法

由此可见,是实践决定方法,不是方法一刀切实践。

更多问题的解决思路在此不再列举,祝阅读之旅愉快!第2章 解析软件架构概念

什么是架构?如果你问五个不同的人,可能会得到五种不同的答案。——lvar Jacobson,《AOSD中文版》

很多人都试图给“架构”下定义,而这些定义本身却很难统一。——Martin Fowler,《企业应用架构模式》

不积跬步,无以至千里。

程序员在向架构师转型时,都希望尽早弄清楚“什么是架构”。但是,架构的定义又多又乱,已造成“什么是架构”成了程序员向架构师转型的“大门槛”。

本章,我们讨论软件架构的概念。

值得说明的是,人们对“Architecture”有着不同的中文叫法,比如架构、构架和体系结构等。本书将一贯地采用“架构”的叫法;当然,当引用原文或提及书名时将保留原来的叫法。2.1 软件架构概念的分类

一个词(比如“电脑”),可能并不代表一件单独的东西,而是代表了一类事物。这个一般性的表述就是我们通常所说的“概念”。

也许读者期待一个干净利落的软件架构概念,但这有点儿难。对此,Martin Fowler给出的评价是:

软件业的人乐于做这样的事——找一些词汇,并将它们引申到大量微妙而又相互矛盾的含义中。一个最大的受害者就是“架构”这个词。……很多人都试图给“架构”下定义,而这些定义本身却很难统一。

本书将软件架构概念分为两大流派——组成派和决策派,帮助各级开发人员快速理清“什么是架构”的基础问题。下面就采用这种方式介绍架构概念。2.1.1 组成派

Mary Shaw 在《软件体系结构:一门初露端倪学科的展望》中,为“软件架构”给出了非常简明的定义:

软件系统的架构将系统描述为计算组件及组件之间的交互。(The arc hitecture of a software system defines that system in terms of computational components and interactions among those components.)

必须说明,上述定义中的“组件”是广泛意义上的元素之意,并不是指和 CORBA、DCOM、EJB 等相关的专有的组件概念。“计算组件”也是泛指,其实计算组件可以进一步细分为处理组件、数据组件、连接组件等。总之,“组件”可以指子系统、框架(Framework)、模块、类等不同粒度的软件单元,它们可以担负不同的计算职责。

上述定义是“组成派”软件架构概念的典型代表,有如下两个显著特点:(1)关注架构实践中的客体——软件,以软件本身为描述对象;(2)分析了软件的组成,即软件由承担不同计算任务的组件组成,这些组件通过相互交互完成更高层次的计算。2.1.2 决策派

RUP(Rational Unified Process,Rational统一过程)给出的架构的定义非常冗长,但其核心思想非常明确:软件架构是在一些重要方面所做出的决策的集合。下面看看它的定义:

软件架构包含了关于以下问题的重要决策:

· 软件系统的组织;

· 选择组成系统的结构元素和它们之间的接口,以及当这些元素相互协作时所体现的行为;

· 如何组合这些元素,使它们逐渐合成为更大的子系统;

· 用于指导这个系统组织的架构风格:这些元素以及它们的接口、协作和组合。

· 软件架构并不仅仅注重软件本身的结构和行为,还注重其他特性:使用、功能性、性能、弹性、重用、可理解性、经济和技术的限制及权衡,以及美学等。

该定义是“决策派”软件架构概念的典型代表,有如下两个显著特点:(1)关注架构实践中的主体——人,以人的决策为描述对象;(2)归纳了架构决策的类型,指出架构决策不仅包括关于软件系统的组织、元素、子系统和架构风格等几类决策,还包括关于众多非功能需求的决策。2.1.3 软件架构概念大观

下面再列举几个著名的软件架构定义,请大家:

· 结合实践,体会自己所认为的“架构”是什么,也可问问周围同事对架构的理解;

· 体会专家们给“架构”下的定义虽多,但万变不离其宗——都是围绕“组成”和“决策”两个角度定义架构的;

· 注意区分,下面的定义1和定义2属于架构概念的“决策派”,而定义3、4、5、6、7属于架构概念的“组成派”;

· 关注定义 7(来自 SEI 的 Len B ass 等人),它将架构的多视图“本性”体现到了定义当中,是相对比较新的定义,业界都深表认同。

1.Booch、Rumbaugh和Jacobson的定义

架构是一系列重要决策的集合,这些决策与以下内容有关:软件的组织,构成系统的结构元素及其接口的选择,这些元素在相互协作中明确表现出的行为,这些结构元素和行为元素进一步组合所构成的更大规模的子系统,以及指导这一组织——包括这些元素及其接口、它们的协作和它们的组合——架构风格。

2.Woods的观点

Eoin W oods 是这样认为的:软件架构是一系列设计决策,如果做了不正确的决策,你的项目可能最终会被取消(Software architecture is the set of de sign deci sions which,if made incorrectly,may cause your project to be cancelled.)。

3.Garlan和Shaw的定义

Garlan 和 Shaw 认为:架构包括组件(Component)、连接件(Connector)和约束(Constrain)三大要素。组件可以是一组代码(例如程序模块),也可以是独立的程序(例如数据库服务器)。连接件可以是过程调用、管道和消息等,用于表示组件之间的相互关系。“约束”一般为组件连接时的条件。

4.Perry和Wolf的定义

Perry和Wolf提出:软件架构是一组具有特定形式的架构元素,这些元素分为三类:负责完成数据加工的处理元素(Processing Ele ments)、作为被加工信息的数据元素(Data Elem ents)及用于把架构的不同部分组合在一起的连接元素(Connecting Elements)。

5.Boehm的定义

Barry Boeh m 和他的学生提出:软件架构包括系统组件、连接件和约束的集合,反映不同涉众需求的集合,以及原理(Rationale)的集合。其中的原理,用于说明由组件、连接件和约束所定义的系统在实现时,是如何满足不同涉众需求的。

6.lEEE的定义

IEEE 610.12-1 990 软件工程标准词汇中是这样定义架构的:架构是以组件、组件之间的关系、组件与环境之间的关系为内容的某一系统的基本组织结构,以及指导上述内容设计与演化的原理(Principle)。

7.Bass的定义

SEI(Software Engineering Institute,SEI,美国卡内基·梅隆大学软件研究所)的 Len B ass等人给架构的定义是:某个软件或计算机系统的软件架构是该系统的一个或多个结构,每个结构均由软件元素、这些元素的外部可见属性、这些元素之间的关系组成。(The softwa re architecture of a program or co mputing sy stem is the struct ure or structures of the sy stem,which co mprise softwar e elements,the externally visible properties of those elements,and the relationships among them.)2.2 概念思想的解析2.2.1 软件架构关注分割与交互

架构设计是分与合的艺术。“软件系统的架构将系统描述为计算组件及组件之间的交互”,Shaw 的这个定义从“软件组成”角度解析了软件架构的要素:组件及组件之间的交互。如图2-1所示(采用UML类图),架构=组件+交互,组件和组件之间有交互关系(图中的“交互”关系建模成UML关联类)。

下面以大家熟悉的MVC架构为例进行说明。如图2-2所示。

· 采用MVC架构的软件包含了这样3种组件:Model、View、Controller。

· 这 3 种组件通过交互来协作:View 创建 Controller 后,Controller 根据用户交互调用Model的相应服务,而Model会将自身的改变通知View,View则会读取Model的信息以更新自身。图2-1 软件架构的要素:组件及组件之间的交互图2-2 MVC架构作为“组件+交互”的例子

通过此例可以看出,“组件+交互”可以将 MVC 等“具体架构设计决策”高屋建瓴地抽象地表达出来。2.2.2 软件架构是一系列有层次的决策

架构属于设计,但并非所有设计都属于架构。架构涉及的决策,往往对整体质量、并行开发、适应变化等方面有着重大影响(否则就放到详细设计环节了):

· 模块如何划分。

· 每个模块的职责为何。

· 每个模块的接口如何定义。

· 模块间采用何种交互机制。

· 开发技术如何选型。

· 如何满足约束和质量属性的需求。

· 如何适应可能发生的变化。

……

还有很多

而且实际的设计往往是分层次依次展开的——无论是决策如何切分系统还是决策技术选型都是如此:

· 例如,你设计一个 C/S 系统时,是不是经历着这样一个“决策树”过程:……嗯,我决定采用 C/S 架构,系统包含 Client 和 Server;……嗯,我决定将 Server 分为三层;……嗯,我决定将Server的引擎层划分为N个模块;……(如图2-3所示。)

· 例如,你设计一个 B/S 系统时,可曾有过这样的“决策过程”:……嗯,我决定 B/S前端采用JSP技术;……嗯,具体到Framework我选Struts;……(如图2-4所示。)再举一例。现在你来设计一个硬件设备调试系统。图2-3 架构设计过程是一棵决策树(切分类决策)图2-4 架构设计过程是一棵决策树(技术选型类决策)

第1步,理解需求——此时软件系统是黑盒子

如图2-5所示,你要设计的系统现在还未切分,它的主要需求目标有:

· 作为设备调试系统,其主要功能是实时显示设备状态,以及支持用户发送调试命令;

· 另外,由于是为硬件产品配套的软件系统,所以它必须容易被测试,否则是硬件故障还是软件故障将很难区分;

· 再就是必须具有很高的性能,具体性能指标为“每秒钟能够刷新 5 次设备状态的显示,并同时支持一个完整命令字的发送”。

第2步,首轮决策——此时软件系统被高层切分

之后,软件架构师必须规划整个系统的具体组成。通常,对于一个独立的软件系统而言,它常常被划分为不同的子系统或分系统,每个部分承担相对独立的功能,各部分之间通过特定的交互机制进行协作。图2-5 设备调试系统:主要目标(CRC卡)

而此例中的设备调试系统则不同,它有两个相对独立的应用组成:一个桌面应用和一个嵌入式应用。

那么,它们如何通信呢?最终决定,将它们通过串口连接,采用RS232协议进行通信。

再接下来,架构师必须决定这两个应用分别担负哪些职责(如图 2-6 中的 CRC 卡所示):桌面应用部分负责提供模拟控制台和状态显示;而嵌入式应用部分负责设备的控制和状态数据的读取。图2-6 设备调试系统:组成部分(CRC卡)

第3~N步,继续决策——此时软件系统被切分成更小单元

……现在,设备调试系统的桌面应用部分,也要划分成模块吧(如图2-7所示)。

通信部分被分离出来作为通信层,它负责在 RS232 协议之上实现一套专用的“应用协议”:当应用层发送来包含调试指令的协议包时,它会按 RS232 协议将之传递给嵌入部分;当嵌入部分发送来原始数据时,它将之解释成应用协议包发送给应用层。

而应用层负责设备状态的显示,提供模拟控制台供用户发送调试命令,并使用通信层和嵌入部分进行交互。

……如此步步设计下去,你就该问自己“架构的哪些目标还未达成”诸如此类的问题了。例如“应用层”怎样高速响应用户?例如“通信层”如何高性能地接受串口数据而不造成数据丢失?在此不再赘述。图2-7 其中的桌面应用:进一步分解(CRC卡)2.2.3 系统、子系统、框架都可以有架构

虽然我们最常听到的说法是“软件系统的架构”,但未必是完整的软件系统才有架构。真实的软件其实是“由组件递归组合而成”的,图2-8运用Composite模式刻画了这一点:

· 组件的粒度可以很小,也可以很大;任何粒度的组件都可以组合成粒度更大的整体。即所谓的粒度多样性问题;

· 组件粒度的界定,必须在具体的实践上下文中才有意义;你的大粒度组件,对我而言可能是原子组件。即所谓的粒度相对性问题;

· 组件分为原子组件和复合组件两种;在特定的实践上下文中,原子组件是不可再分的;复合组件是由其他组件(既可以是原子组件,又可以是复合组件)组合而成的;无论是原子组件还是复合组件,它们之间都可以通过交互来完成更复杂的功能。图2-8 借助Composite模式刻画真实的软件

是时候为“软件架构”找准位置了,答案看上去惊人的简单(如图2-9所示):

· 架构设计是针对作为复合整体的“复杂软件单元”的,架构规定了“复杂软件单元”如何被设计的重要决策;

· 实际上,系统、子系统和框架(Framework)根据需要都可以进行架构设计。图2-9 为“软件架构”找准位置

例如,航空航天领域的系统往往极为复杂,这样一来,总的系统需要配备系统架构师,子系统有时也会分别单独配备架构师。

又例如,用友华表 Cell 组件是标准的报表处理 ActiveX 组件,它提供几百个编程接口。虽然在用户看来它只是小小的“开盒即用”的ActiveX 组件(上面说的“原子组件”),但它的研发团队从需求分析到架构设计到程序开发……都样样经历(上面说的“复杂软件单元”)。

再例如,随着面向服务架构(Service Oriented Architecture,SOA)被越来越多的人所接受,基于组件的软件工程(Component Based Software Engineering,CBSE)也为更多的人所认识。在此种情况下,整个系统的架构模式是 SOA,而每个组件本身也有自己的架构设计——在实践中不了解这一点会很危险。

推广开去,其实任何作为复合整体的复杂事物都可能有架构,比如一本书、一幢建筑物。那本“永不褪色的经典”《如何阅读一本书》中就说:“每一本书的封面之下都有一套自己的骨架(Every book has a skeleton hidden between its boards)。”2.3 实际应用(1)——团队对架构看法不一怎么办2.3.1 结合手上的实际工作来理解架构的含义

你们公司,你所在的部门,是否存在这样的问题:不同的人对架构有不同的理解?

看法影响做法。先说程序员。如果程序员们对他们公司架构师的做法“不以为然”,会不会不按照架构进行后续的详细设计和编程呢?……这让我们不禁想到,程序代码实际体现的设计和《架构设计文档》差别很大,是很多公司都存在的现象。这背后,难道没有“程序员和架构师对架构有不同的理解”这一原因吗!

再说架构师。如果一个架构师认为“架构就是通用模块”,那么他可能就不会关心非通用单元的设计。如果一个架构师认为“架构就是技术选型”,那么他在拍板儿选择“Spring+S truts”之后就理所当然地无事可做了。如果一个架构师认为“投标时讲的架构就是架构的全部”,那么他才不管那“三页幻灯”对程序员的实际开发指导不够呢(因为没有意识到)。

怎么办呢?

一通理论说教是不行的。太空洞,到了实际工作中,理解依然、做法照旧。

结合手上的实际工作来理解架构的含义,是笔者推荐的做法。2.3.2 这样理解“架构”对吗

某公司,研发二部,他们一直在做的软件产品叫PM Suite,是一套项目管理系统。

老王,研发二部部长,经验丰富、设计功力也非常深厚。

小张,众多程序员的代表,开发骨干,功底扎实、头脑灵活、工作努力。小张希望能在 1~2年之内,从程序员转型成为架构师。

关于“什么是架构”,小张是这么理解的:

在一些大型项目或者大型公司里,都是由架构师编写出系统接口,具体的实现类交给了程序员编写,公司越大这种情况越明显,所以在这些公司里做开发,我们可能都不知道编写出的系统是个什么样子,每天做的工作可能就是做“填空题”了。

当你发现越来越灵活地使用接口时,那么你就从程序员升级为架构师了。

老王用3个公式概括了一下小张的理解:

程序=类+类级接口

架构设计=定义类级接口

编程开发=像做填空题似的写实现类

这可行吗?将架构设计一下子细致到类:一是难度太大不现实,二是工作量太大没必要,三是并发呀部署呀都没考虑、性能安全可伸缩等需求能达标?……于是老王开始担心了。2.3.3 工作中找答案:先看部分设计

老王找来小张,铺开纸笔,开始拿实际工作来“说事儿”。他说:

咱们的 PM Su ite 系统,有一项名为“查看甘特图”的需求,用户要求“能够以甘特图方式查看任务的起始时间、结束时间、任务承担者等信息”。经过分析我们不难发现,PM Suite 至少应提供两种查看任务计划的方式:一种是以表格的方式将任务名称、开始时间等信息列出,另一种是采用甘特图。如图2-10所示。图2-10 PM Suite至少要提供两种查看任务计划的方式

任务是如何计划的?又具体分配给哪些项目成员?这些信息和 PM Su ite 采用何种方式来展现应当是没有关系的。根据此分析,我们立即想到采用 MVC 架构,将业务逻辑和展现逻辑分开,如图2-11所示。图2-11 和具体技术无关的架构方案

上面的架构设计,还处于“和具体技术无关”的层面。我们必须考虑更多的实际开发中要涉及的技术问题,从而不断细化架构方案,这样才能为开发人员提供更多的指导和限制,也才能真正降低后续开发中的重大技术风险。

对于 PM Suite 要显示甘特图而言,“甘特图绘制包”是自行开发的,还是采用的第三方SDK,就是一个很重要的技术问题。考虑如下:

· 一方面,用户根本不关心“甘特图绘制包”的问题,他们只在乎自己的需求是否得到了满足;而项目工期是很紧的,自行开发“甘特图绘制包”势必增加其他工作的压力,为什么不采用第三方SDK呢?

· 另一方面,短期内决定采用的第三方“甘特图绘制包”可能并不是最优的,所以并不希望PM Suite“绑死”在特定“甘特图绘制包”上。

基于以上分析,架构师会决定:采用第三方 SDK,但会自主定义“甘特图绘制接口”将SDK隔离。如图2-12所示。图2-12 和技术相关的架构方案

有的读者应该已经看出来了,上述设计中采用了Adapter设计模式。

适配器(Adapter)模式

关键字:已存在/不可预见 复用

支持变化:由于 Adapter 提供了一层“间接”,使得我们可以复用一个接口不符合我们需求的已存在的类,也可以使一个类(Adaptee)在发生不可预见的变化时,仅仅影响 Adapter而不影响Adapter的客户类。

结构:2.3.4 工作中找答案:反观架构概念的体现

看到小张听得挺有感觉,老王话锋一转,话题落于架构的理解上。他说:

有关PM Suit e的设计,先讲到这儿,我再简单说一下“什么叫架构”。架构的定义很乱,但可以分为两派。

组成派:架构=组件+交互

决策派:架构=一组重要决策

刚才有关 PM Suite 的设计虽然仅涉及架构的“冰山一角”,但仍然可以体现软件架构的概念——对组成派和决策派的架构概念都有体现。

先说组成派的架构概念,它强调软件架构包含了“计算组件及组件之间的交互”。组件体现在哪里呢?

· 【回顾图 2-11】。“业务层”和“展现层”就是两个组件;当然,这两个组件粒度很粗,并且完全是黑盒。

· 【到了图 2-12】。为了支持 MVC 协作机制,设计中引入了 PrgMgtModel、GanttChart和 GanttChartImpl 等关键类。可以说,“业务层”和“展现层”两个组件在某种程度上已从黑盒变成了灰盒,从而能提供更具体的开发指导。

那么,软件架构概念中所说的“交互”体现在哪里呢?

· 【回顾图 2-11】。“业务层”和“展现层”两个粗粒度组件之间的交互为:展现层从业务层“读取数据”。

· 【到了图 2-12】。“读取数据”这一交互已经“具体落实”成了“GanttChartImpl 从PrgMgtModel读取数据”。另外,图中还有两个“调用”关系。

由此看来,组成派软件架构概念完全是对架构设计方案的忠实概括,只不过有一点儿抽象罢了。

再看看决策派的架构概念,它归纳了架构决策的类型,指出架构决策不仅包括关于软件系统的组织、元素、子系统、架构风格等的几类决策,还包括关于众多非功能需求的决策。

· 【回顾图 2-11】。业务层和展现层分离,体现了架构概念中的“软件系统的组织”决策,业界也普遍认同。

· 【到了图2-12】。为了防止PM Suite“绑死”在特定甘特图绘制包上,设计中引入自主定义的GanttChart接口,让实现该接口的GanttChartImpl转而调用第三方SDK(其实就是 Adapter 设计模式)。这样一来,架构就有了弹性——当发现功能更强大的甘特图程序包时(或决定直接调用Java 2D自行开发甘特图绘制部分时),可以方便地仅更改GanttChartImpl,而其他组件不用更改(如图2-13所示)。图2-13 软件架构如何具有弹性

老王最后说:呵呵,组成派和决策派无非是个叫法,它们只不过是所站的角度不同罢了,你在具体设计一个架构时都会有所体现的。第3章 理解架构设计视图“有角度就有空间”。……多视图方法背后的核心思想有些相似:从不同角度,规划“分割”与“交互”。——温昱,《一线架构师实践指南》

不同的视图支持不同的目标和用途。——Paul Clements,《软件构架编档》

架构设计是一门解决复杂问题的艺术。

设计任何复杂系统时,架构视图都是不可或缺的(无一例外)。但由于在日常开发工作中较少接触,大部分程序员对“设计视图”的思想还比较陌生。

本章围绕“架构视图”这一主题,将逐次讨论:

· 设计架构时,架构视图为什么必不可少?【本章问题1】

· 什么是架构视图?【本章问题2】

· 如何运用“逻辑视图+物理视图”设计一个系统的架构?【本章问题3】3.1 软件架构为谁而设计

办公室里,关于什么是软件架构,争论正酣。

程序员说,软件架构就是要决定需要编写哪些 C 程序或 OO 类、使用哪些现成的程序库(Library)和框架(Framework)。程序经理笑了。

程序经理说,软件架构就是模块的划分和接口的定义。系统分析员笑了。

系统分析员说,软件架构就是为业务领域对象的关系建模。配置管理员笑了。

配置管理员说,软件架构就是开发出来的以及编译过后的软件到底是个啥结构。数据库工程师笑了。

数据库工程师说,软件架构规定了持久化数据的结构,其他一切只不过是对数据的操作而已。部署工程师笑了。

部署工程师说,软件架构规定了软件部署到硬件的策略。用户笑了。

用户说,软件架构应该将系统划分为一个个功能子系统。程序员又笑了。

大家想了想说,我们都没错呀,所有这些方面都是需要的啊。……软件架构师哭了。

由此看来,不同涉众看待架构的视角是不同的,而架构师要为不同的涉众而设计。

怎么办呢?同时关注多个架构设计视图。架构视图的本质是“分而治之”,能帮助架构师从不同角度设计,特别是面对复杂系统时“分而治之”地设计是必需的。

这就回答了“设计架构时,架构视图为什么必不可少”的问题【本章问题1】。3.1.1 为用户而设计

为什么要开发某个软件系统呢?因为要给用户使用:或辅助用户完成日常工作,或帮助用户管理某些信息,或给用户带来娱乐体验……不一而足。

用户要功能,用户也要质量。

每套软件都会提供这样或那样的功能,正是这些功能帮助用户实现他们在工作或生活中的特定目标。用户所需的功能和系统本身的结构一定是相互影响的,这正是软件架构师要特别关注的。先举个生活中的例子吧。例如,因为功能不尽相同,所以“转笔刀”的结构和“专用刀片”的结构也不一样(如图 3-1 所示):小学生需要削铅笔,那一定是转笔刀最适合他们,因为方便易用,一转即可;而美术师需要用铅笔来画素描,他们则需要使用专用刀片,因为转笔刀难以削出满足不同绘画要求的形状各异的笔尖。同样,对于软件系统而言,用户需求是千差万别的,我们采用的软件架构必须和所要提供的功能相适应。因此,软件架构师必须时时牢记:为用户而设计。图3-1 生活中的例子:功能与结构相互影响

诸如性能、易用性等软件质量属性,并不像上面所述的软件功能那样直接帮助用户达到特定目标,但并不意味着软件质量属性不是必需的——恰恰相反,质量属性差的软件系统大多都不会成功。例如,你提供了用户要求的“交易查询”功能,但这一功能动辄就需要花上几分钟,用户能接受吗?当然不能接受。用户会说,功能虽然具备了,但质量太差难以接受。用户在使用软件系统的过程中,其关心的质量属性可能包括易用性、性能、可伸缩性、持续可用性和鲁棒性等。因此,软件架构师也应当时时牢记:为用户而设计,不仅满足用户要求的功能,也要达到用户期望的质量。3.1.2 为客户而设计

很多时候,客户(Customer) ≠ 最终用户(User)。

例如,对超市销售系统而言,客户是某家连锁超市(的老板),而用户则是超市收银员和上货员。

架构师为客户而设计:充分考虑客户的业务目标、上线时间的要求、预算限制,以及集成需要等,还要特别关注客户所在领域的业务规则和业务限制。为此,架构师应当直接或(通过系统分析员)间接地了解和掌握上述需求及约束,并深刻理解它们对架构的影响,只有这样才能设计出合适的软件架构。合适的才是最好的,例如,如果客户是一家小型超市,软件和硬件采购的预算都很有限,那么你就不宜采用依赖太多昂贵中间件的软件架构设计方案。3.1.3 为开发人员而设计

先研究需求,再设计架构,然后交由开发人员编程……作为架构,不仅要为“上游”的需求而设计,还要为“下游”的开发人员而设计。

例如,性能是软件运行期质量属性,最关心性能的人其实是客户;但可扩展性是软件开发期质量属性,项目开发人员和负责升级维护的开发人员最关心。

推及开去,其实,并不是所有需求都来自用户,软件的可扩展性、可重用性、可移植性、易理解性和易测试性等非功能需求更多地考虑对开发人员的影响。这类“软件开发期质量属性”深刻影响开发人员的工作,使开发更顺畅抑或更艰难。3.1.4 为管理人员而设计

软件变得越来越复杂,单兵作战不再普遍,取而代之的是团队开发。而团队开发又反过来使软件开发更加复杂,因为现在不仅仅要面临技术复杂性的问题了,还有管理复杂性的问题。

开发人员之间的依赖,源自他们负责的程序之间的依赖(如图 3-2 所示)。要理清并管理人员协作,就应该搞清楚系统一级“模块+交互”的设计,搞清楚架构。可见,架构是开发管理的核心基础。图3-2 开发人员之间的依赖,源自他们负责的程序之间的依赖

看来,软件架构师也应为管理人员而设计。

例如,对软件项目管理而言,软件架构应当起到应有的作用:为项目经理制定项目计划、管理项目分工和考核项目进度等提供依据。一方面,软件架构从大局着手,就技术方面的重大问题作出决策,构造一个由粗粒度模块组成的解决方案,从而可以把不同模块分配给不同小组分头开发。另一方面,软件架构设计方案规定了各模块之间如何交互的机制和接口,在开发小组之间起到“沟通桥梁”和“合作契约”的作用。

再例如,对软件配置管理而言,软件架构师亦应顾及。一般而言,在软件架构确定之前,软件配置管理是无法全面开展的。配置管理员应该能够从软件架构方案中了解到开发出来的软件以什么样的目录结构存在,以及编译过后的软件目标模块放到哪个目录等决定,并以此作为制定配置管理基本方案的基础。3.1.5 总结

架构师应当为项目相关的不同角色而设计(如图 3-3 所示)——只有这样,软件架构才能和它“包含了关于如何构建软件的一些最重要的设计决策”的“地位”相符。图3-3 软件架构为谁而设计

· 架构师要为“上游”客户负责,满足他们的业务目标和约束条件;

· 架构师要为“上游”用户负责,使他们关心的功能需求和运行期质量属性得以满足;

· 架构师必须顾及处于协作分工“下游”的开发人员;

· 架构师还必须考虑“周边”的管理人员,为他们进行分工管理、协调控制和评估监控等工作提供清晰的基础。3.2 理解架构设计视图

什么是架构视图呢?【本章问题2】3.2.1 架构视图

架构视图的实践导向性很强,每个视图分别关注不同的方面,针对不同的实践目标和用途。Philippe Kruchten在其著作《Rational统一过程引论》中写道:

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

架构视图是一种设计架构、描述架构的核心手段:

· 也就是说,架构要涵盖的内容和决策太多了,超过了人脑“一蹴而就”的能力范围,因此采用“分而治之”的办法从不同视角分别设计;

· 同时,也为软件架构的理解、交流和归档提供了方便。

在多种架构视图中,最常用的是逻辑架构视图和物理架构视图(本章稍后讨论如何运用“逻辑视图+物理视图”设计架构)。3.2.2 一个直观的例子

在讲解软件的逻辑架构视图和物理架构视图之前,先看一个生活中视图的例子。

图 3-4 所示的世界人口分布图,是社会学家关心的;而气候学家,则更关心图 3-5 所示的世界年降水量分布图。这其实就运用了“视图”的手段,用不同视图来刻画我们关心的世界的不同方面——你完全可以将“世界人口分布图”称为“世界的人口分布视图”。

当然,更进一步而言,同一事物的不同视图之间是有联系的。例如,从图 3-4 和 3-5 上看,除了南美洲之外基本都是降水量足的地方人口较密集。我们下面将讨论的软件架构视图也是这样,不同视图之间存在相互影响。图3-4 世界人口分布图(图片来源:www.dlpd.com)图3-5 世界年降水量分布图(图片来源:www.dlpd.com)3.2.3 多组涉众,多个视图

首先,考虑软件架构的表达与交流。

这是个很现实的问题。究其原因,由于角色和分工不同,整个软件团队以及客户等涉众各自需要掌握的技术或技能存在很大差异,为了完成各自的工作,他们需要了解整套软件架构决策的不同子集。所以,软件架构师应当提供不同的软件架构视图,以便交流和传递设计思想。例如:

· 系统工程师:由于负责部署和运营维护,他们最关心软件系统基于何种操作系统之上、依赖于哪些软件中间件、有没有群集或备份等部署要求、驻留在不同机器上的软件部分之间的通信协议是什么等决策;

· 而开发人员:则最关心软件架构方案中关于模块划分的决定、模块之间的接口如何定义、甚至架构指定的开发技术和现成框架是不是最流行的等问题;

……

不一而足。

相反,如果不同视图混为一谈,《架构文档》理解起来会非常困难、甚至看不懂。对此,Peter Herzum等人在Business Component Factory一书中曾指出:

总的来说,“架构”一词涵盖了软件架构的所有方面,这些方面紧紧地缠绕在一起,决定如何将之分割成部分和主题显得相当主观。既然如此,就必须引入“架构视点”作为讨论、归档和理解大型系统架构的手段。(Generally speaking,the term architecture can be seen as covering all a spects of a soft ware architect ure.All its aspects re deeply intertwined,an d it is really a subj ective decisi on to split it up in parts and su bjects.Having said that,the u sefulness of int roducing archit ectural viewp oints is e ssential as a way of discussing,documenting,and mastering the architecture of large-scale systems.)

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载