http://jpkc.whu.edu.cn/jpkc/dxqyxxxtfgnjg/dzja/dzjc/jc2.htm
1 解析软件架构概念
1.1 软件架构的历史
早在1960年代,诸如E·W·戴克斯特拉就已经涉及软件架构这个概念了。自1990年代以来,部分由于在 Rational Software Corporation内部的相关活动,软件架构这个概念开始越来越流行起来。
卡内基梅隆大学和加州大学埃尔文分校在这个领域作了很多研究。卡内基·梅隆大学的Mary Shaw和David Garlan于1996年写了一本叫做 《Software Architecture Perspective on an Emerging Discipline》的书,提出了软件架构中的很多概念,例如软件组件、连接器、风格等等。加州大学埃尔文分校的软件研究院所做的工作则主要集中于架构风格、架构描述语言以及动态架构。
计算机软件的历史开始于五十年代,历史非常短暂,而相比之下建筑工程则从石器时代就开始了,人类在几千年的建筑设计实践中积累了大量的经验和教训。建筑设计基本上包含两点,一是建筑风格,二是建筑模式。独特的建筑风格和恰当选择的建筑模式,可以使一个独一无二。
软件与人类的关系是架构师必须面对的核心问题,也是自从软件进入历史舞台之后就出现的问题。与此类似地,自从有了建筑以来,建筑与人类的关系就一直是建筑设计师必须面对的核心问题。英国首相丘吉尔说,我们构造建筑物,然后建筑物构造我们(We shape our buildings, and afterwards our buildings shape us)。英国下议院的会议厅较狭窄,无法使所有的下议院议员面向同一个方向入座,而必须分成两侧入座。丘吉尔认为,议员们入座的时候自然会选择与自己政见相同的人同时入座,而这就是英国政党制的起源。Party这个词的原意就是“方”、“面”。政党起源的关键就是建筑物对人的影响。在软件设计界曾经有很多人认为功能是最为重要的,形式必须服从功能。与此类似地,在建筑学界,现代主义建筑流派的开创人之一Louis Sullivan也认为形式应当服从于功能(forms follows function)。
几乎所有的软件设计理念都可以在浩如烟海的建筑学历史中找到更为遥远的历史回响。最为著名的,当然就是模式理论和XP理论。
1.2 软件架构的两大流派
1.2.1 软件架构概念:组成派
关于软件架构的概念,有太多版本,这对我们的实践也造成了很多麻烦。笔者认为,可以将这些概念大致分为两大流派:组成派和决策派。
Mary Shaw在《软件体系结构:一门初露端倪学科的展望》中,为“软件架构”给出了精致利索的定义:
软件系统的架构将系统描述为计算组件及组件之间的交互(The architecture of a software system defines that system in terms of computational components and interactions among those components.)。
必须说明,上述定义中的“组件”是广泛意义上的元素之意,并不是指和CORBA、DCOM、EJB等相关的专有的组件概念;“计算组件”也是泛指,其实计算组件可以进一步细分为处理组件、数据组件、连接组件等。总之,“组件”可以指子系统、框架、模块、类等不同粒度的软件单元,它们可以担负不同 的计算职责。
上述定义是组成派软件架构概念的典型代表,有如下两个显著特点:
l 关注架构实践中的客体——软件,以软件本身为描述对象;
l 分析了软件的组成,即软件由承担不同计算任务的组件组成,这些组件通过相互交互完成更高层次的计算目的。
1.2.2 软件架构概念:决策派
下面来看看RUP(Rational Unified Process,Rational统一过程)为软件架构下的定义:
软件架构包含了关于以下问题的重要决策:
l 软件系统的组织;
l 选择组成系统的结构元素和它们之间的接口,以及当这些元素相互协作时所体现的行为;
l 如何组合这些元素,使它们逐渐合成为更大的子系统;
l 用于指导这个系统组织的架构风格:这些元素以及它们的接口、协作和组合。
l 软件架构并不仅仅注重软件本身的结构和行为,还注重其他特性:使用、功能性、性能、弹性、重用、可理解性、经济和技术的限制及权衡、以及美学等。
上述定义看似冗长,其实核心思想非常明确:软件架构是在一些重要方面所做出的决策的集合。
该定义是决策派软件架构概念的典型代表,有如下两个显著特点:
l 关注架构实践中的主体——人,以人的决策为描述对象;
l 归纳了架构决策的类型,指出架构决策不仅包括关于软件系统的组织、元素、子系统、架构风格等的几类决策,还包括关于众多非功能需求的决策。
1.3 PMTool案例:领会架构概念
为了有助于领会软件架构的概念,我们引入一个名为“PM Tool”的案例。PM Tool是一个项目管理系统,提供项目计划、任务管理和资源管理等功能。本节希望结合案例来讨论软件架构,为读者理解软件架构的概念带来实感。
1.3.1 案例故事
PM Tool有一项名为“查看甘特图”的需求,用户要求“能够以甘特图方式查看任务的起始时间、结束时间、任务承担者等信息”。经过分析我们不难发现,PM Tool至少应提供两种查看任务计划的方式:一种是以表格的方式将任务名称、开始时间等信息列出,另一种是采用甘特图。如图1-6所示。
图1-6 PM Tool至少要提供两种查看任务计划的方式
任务是如何计划的?又具体分配给哪些项目成员?这些信息和PM Tool采用何种方式来展现应当是没有关系的。根据此分析,我们立即想到采用MVC架构,将业务逻辑和展现逻辑分开,如图1-7所示。
图1-7 和具体技术无关的架构方案
上面的架构设计,还处于“和具体技术无关”的层面。我们必须考虑更多的实际开发中要涉及到的技术问题,从而不断细化架构方案,这样才能为开发人员提供更多的指导和限制,也才能真正降低后续开发中的重大技术风险。
对于PM Tool要显示甘特图而言,“甘特图绘制包”是自行开发的,还是采用的第三方SDK,就是一个很重要的技术问题。考虑如下:
一方面,用户根本不关心“甘特图绘制包”的问题,他们只在乎自己的需求是否得到了满足;而项目工期是很紧的,自行开发“甘特图绘制包”势必增加其他工作的压力,为什么不采用第三方SDK呢?
另一方面,短期内决定采用的第三方“甘特图绘制包”可能并不是最优的,所以并不希望PM Tool“绑死”在特定“甘特图绘制包”上。
基于以上分析,架构师会决定:采用第三方SDK,但会自主定义“甘特图绘制接口”将SDK隔离。如图1-8所示。
图1-8 和技术相关的架构方案
有的读者应该已经看出来了,上述设计中采用了Adapter设计模式。
适配器(Adapter)模式 关键字:已存在/不可预见 复用 支持变化:由于Adapter提供了一层“间接”,使得我们可以复用一个接口不符合我们需求的已存在的类,也可以使一个类(Adaptee)在发生不可预见的变化时,仅仅影响Adapter而不影响Adapter的客户类。 结构:
|
1.3.2 软件架构概念的体现
有关PM Tool的案例故事先讲到这儿,虽然其中仅涉及到架构设计方案的一小部分,但仍然可以体现软件架构的概念——对组成派和决策派的架构概念都有体现。
先说组成派的架构概念,它强调软件架构包含了“计算组件及组件之间的交互”。组件体现在哪里呢?
在图1-7所展示的设计中,“业务层”和“展现层”就是两个组件;当然,这两个组件粒度很粗,并且完全是黑盒。
到了图1-8所展示的设计中,黑盒虽然没有完全变成白盒,但支持 MVC协作机制的一部分关键类已经明确——PrgMgtModel、GanttChart和GanttChartImpl都是粒度较细的组件,可以说,“ 业务层”和“展现层”两个组件在某种程度上已从黑盒变成了灰盒,从而能提供更具体的开发指导。
那么,软件架构概念中所说的“交互”体现在哪里呢?
对于图1-7所展示的设计,“业务层”和“展现层”两个粗粒度组件之间的交互为:展现层从业务层“读取数据”。
“读取数据”这一交互到了图1-8的设计依然存在,但此职责已经“具体落实”成了“GanttChartImpl从PrgMgtModel读取数据”。另外,图1-8的设计中,两个“调用”关系也是软件架构的概念中“交互”的具体例子。
由此看来,组成派软件架构概念完全是对架构设计方案的忠实概括,只不过有一点儿抽象罢了。
再看看决策派的架构概念,它归纳了架构决策的类型,指出架构决策不仅包括关于软件系统的组织、元素、子系统、架构风格等的几类决策,还包括关于众多非功能需 求的决策。图1-7所展示的设计那么简单,也包含了设计决策吗?是的,业务层和展现层分离,体现了架构概念中的“软件系统的组织”决策,这一设计决策早已 得到了业界的普遍认同。
下面再举个例子,来说明软件架构中的设计决策是如何支持“使用、功能性、性能、弹性、重用、可理解性、经济和技术的限制及权衡,以及美学等”非功能需求的。 仅以“弹性”为例吧。为了防止PM Tool“绑死”在特定甘特图绘制包上,架构设计之时作了如下决策(参见图1-8):引入自主定义的GanttChart接口,让实现该接口的 GanttChartImpl转而调用第三方SDK(其实就是Adapter设计模式)。这样一来,架构就有了弹性——当发现功能更强大的甘特图程序包时 (或决定直接调用Java 2D自行开发甘特图绘制部分时),可以方便地仅更改GanttChartImpl,而其他组件不用更改(如图1-9所示)。
图1-9 软件架构如何具有弹性
1.3.3 重要结论
通过上述分析,我们高兴地看到:组成派和决策派软件架构概念并不矛盾,它们只不过是所站的角度不同罢了;在具体的软件架构实践中,总是同时体现着这两“派”的架构概念。
2 子系统、框架与架构
2.1 子系统和框架在架构设计中的地位
2.1.1 关注点分离之道
好的架构设计必须把变化点错落有致地封装到软件系统的不同部分,为此,必须进行关注点分离。Ivar Jacobson在《AOSD中文版》中写道:
好的架构必须使每个关注点相互分离,也就是说系统中的一部分发生了改变,不会影响其他部分。即使需要改变,也能够清晰地识别出哪些部分需要改变。如果需要扩展架构,影响将会最小化。已经可以工作的每个部分都将继续工作。
那么,如何通过关注点分离来达到“系统中的一部分发生了改变,不会影响其他部分”的目标呢?
首先,可以通过职责划分来分离关注点。面向对象设计的关键所在,就是职责的识别和分配。每个功能的完成,都是通过一系列职责组成的“协作链条”完成的;当不同职责被合理分离之后,为了实现新的功能只需构造新的“协作链条”,而需求变更也往往只会影响到少数职责的定义和实现。无论是对象、模块,还是子系统,它们所承担的职责都应该具有高内聚性,否则对象之间的松耦合性就失去了基础,成为空谈。架构模式和设计模式为特定上下文中重复出现的问题提供了通用的职责划分方案。
其次,可以利用软件系统各部分的通用性的不同进行关注点分离。不同的通用程度意味着变化的可能性不同,将通用性不同的部分分离有利于通用部分的重用,也便于对专用部分进行修改。打个比方,一座高楼大厦要想稳固,必须考虑不同部分的热胀冷缩系数的差异,将不同“膨胀比”的部分硬连在一起容易引起“开裂”,这个比喻很好地说明了“稳固的架构”的含义。广为人知的框架技术可以用于分离通用部分,而元模型驱动方法是另一种分离通用性部分的技术。
另外,还可以先考虑大粒度的子系统,而暂时忽略子系统是如何通过更小粒度的模块和类组成的。在实际中,软件架构师常常将系统划分为一组子系统,并为子系统定义明确的接口,其中的细节将随其后的开发工作慢慢展开。这样做可以避免陷入过多的细节当中,所谓“忘却是一种能力”,就是指架构师必须有在更高层面思考的能力。
图2-1总结了上述的架构设计关注点分离原理。可以说,根据职责分离关注点、根据通用性分离关注点、根据不同粒度级别分离关注点是3种位于不同“维度”的思维方式,所以在实际工作中必须综合运用这些手段。
图2-1 架构设计关注点分离原理
2.1.2 子系统和框架在架构设计中的地位
软件界是新名词制造工厂,这可能是其他任何产业都难以望其项背的。但在这背后,深藏着的是相对稳定的“解决之道”。根据我们上一节讲述的关注点分离原理,归纳了一些流行技术所处的位置,如图2-2所示。
图2-2 技术谱
例如,无论是架构模式还是设计模式,重点关注的都是如何提供一个“协作模型”,这个协作模型通过明确协作中不同角色所担负的职责,达到“为特定上下文中的问题提供解决方案”的目的。来看看抽象工厂(Abstract Factory)设计模式,它是常见的设计模式之一。图2-3以“上下文-问题-解决方案”的形式总结了抽象工厂设计模式:我们遇到的设计问题是如何实现一系列对象的实例化,并且问题所处的上下文是“不同的应用场景需要不同系列的对象实例“;最终,抽象工厂的解决方案是“为创建系列对象提供统一接口,为如何实际创建提供不同实现”。显然,如果没有“不同的应用场景需要不同系列的对象实例”上下文限制,我们的设计可能仅仅是个普通的对象工厂。
图2-3 抽象工厂设计模式
抽象工厂(Abstract Factory)模式 关键字:不同系列的对象实例 支持变化:便于切换不同系列的对象实例,便于修改对象实例的具体创建过程。 结构:
(图片来源:《设计模式》) |
于是,我们就不难理解本章将重点讨论的子系统和框架技术在架构设计 中的重要地位了。例如,现在的软件开发越来越倚重框架的使用,因此选择何种框架,每个框架在整个架构中处在什么位置,都成为软件架构设计的重要环节。Ivar Jacobson就曾指出,“设计应该把类库和框架的用法反映出来”。框架技术有助于把通用关注点和专用关注点分离开来,结果是带来了更好的易修改性和可重用性。框架支持我们引入一个全新的关注点分离维度,并且它和分层架构有很好的结合。
2.2 子系统与软件架构
了解子系统与软件架构的关系有两个方面的意义。
从解决问题的角度而言,了解子系统与软件架构的关系,有助于避免软 件架构设计不足和高来高去的问题。软件架构要设计到什么程度?为了使软件架构能够为软件开发提供足够的指导和限制,软件架构师应当为复杂 的子系统设计架构,而不是保持其黑盒子的状态止步不前。
从经验的运用角度而言,了解子系统与软件架构的关系,有助于充分利用架构设计技能。比如,有经验的软件架构师都知道,分层、MVC和管道过滤器等架构模式很少单独使用,而是结合使用或根据子系统的层次划分嵌套使用。如图 2-5所示,就是一个分层架构模式和MVC架构模式结合使用的例子。
图2-5 分层架构和MVC架构结合使用的例子
2.2.1 不同粒度的软件单元
作为软件架构师,必须思考“软件单元是如何组成粒度更大的整体的”这一问题。
在具体的架构实践中,一个软件系统往往首先分解为几个子系统,子系统又继续分解,如图2-6所示,它刻画了这样的软件分解场景:一个系统,由3个子系统组成;每个子系统,又由组成它的多个类来实现。子系统可以分配到开发组,每个类可以分配给具体的工程师实现。
图2-6 一个软件分解场景
更广泛而言,构成软件的单元具有不同的粒度等级。对于面向对象的软件开发而言,经常有这些软件单元:
l 粒度最小的单元通常是“类”;
l 几个类紧密协作形成“模块”;
l 完成相对独立的功能的多个模块构成了“子系统”;
l 多个子系统相互配合才能满足一个完整应用的需求,从而构成了软件“系统”;
l 一个大型企业往往使用多套系统,多套系统通过互操作形成“集成系统”。
类、模块、子系统、系统、集成系统,都是软件单元的具体形态,只不过粒度不同罢了。软件系统越复杂,不同粒度的分解层次就越多;比如,有的组织会引入“分系统”的概念,形成“系统-分系统-子系统-模块”的分级体系。
2.2.2 子系统也有架构
所谓系统,是指由多个元素组成的逻辑实体,它完成一组特定的目标或担负一定的职责。系统可以仅包含软件,也可以仅包含硬件,或者是两者都包含。
子系统是特殊的系统——只不过在特定的上下文中,这个系统作为更大的系统的一部分出现。
系统需要架构设计,而子系统如果足够复杂,则也需要架构设计。图2-7揭示了这一点:子系统作为特殊的系统,它也是由多个元素组成的整体,而架构规定了它是如何划分为多个部分的,以及规定了多个部分之间的交互机制和交互接口。
图2-7 子系统也有架构
2.2.3 子系统不同,架构不同
另外,不同类型的软件系统需要不同的软件架构设计,这似乎是很多人都理解的道理;但有时候,一个系统的不同子系统也应当有不同的软件架构。
举个例子。相信不少读者了解Martin Fowler所著的《企业应用架构模式》中介绍的事务脚本模式(Transaction Script)、领域模型模式(Domain Model)等“领域逻辑模式”。在实际的架构设计当中,这些模式的运用并不是“放之各子系统而皆准”的。例如,一个采用了分层架构的软件系统,它可能包 含了报表、拓扑显示等子系统,这些子系统会有自己的内部架构吗?
图2-8所示的示意图给出了结论:拓扑子系统适宜采用领域模型架构模式,而报表子系统则应采用事务脚本架构模式。
图2-8 不同子系统采用不同软件架构的例子
对于此例,如果你熟悉网管软件,你可以想象这是个网络设备拓扑图的显示子系统;如果你熟悉UML建模,你可以想象这是个UML建模工具。拓扑子系统的业务逻辑复杂,诸如图元的排列、连接、移动、覆盖、复制和删除等问题涉及到不同的规则,应当充分利用对象模型的优势来解决这些问题。
至于此例中的报表子系统,其业务逻辑相对比较简单,通过SQL语句从数据库中提取数据非常方便,并且可以利用SQL语句进行一些统计和查找计算,因此宜于采用事务脚本模式(转而采用领域模型模式无疑是自找麻烦);当然,报表子系统采用事务脚本模式对提高性能也大有好处。
2.3 框架与软件架构
2.3.1 框架的概念
框架的定义是:框架是可以通过某种回调机制进行扩展的软件系统或子系统的半成品。
首先,框架是半成品,这是它和其他所有软件组件的本质区别。这涉及到“软件重用”的一对内在矛盾:“重用几率”大小和“重用所带来的价值量”大小之间的矛盾。简言之,软件单元的粒度越大,则重用所带来的价值量越大,但重用几率越小;反之,粒度小的软件单元被重用的几率越大,则重用所带来的价值量就越小。框架的智慧就在于此:为了追求重用所带来的价值量最大化,将容易变化的部分封装成扩展点,并辅以回调机制将它们纳入框架的控制范围之内,从而在兼顾定制开销的同时使被重用的设计成果最多。
下面,来解释一下“某种回调机制”的含义。框架并不一定必须用面向对象编程语言实现,如C语言等传统编程语言可以通过函数指针作为参数来实现回调机制,而面向对象编程语言中利用抽象方法(C++中称为虚函数)支持回调机制——无论是抽象类还是接口都利用了抽象方法。
Frank Buschmann等人在《面向模式的软件体系结构(第一卷)》中为框架所下的定义,非常重视框架与架构的关系:
框架是一个可实例化的、部分完成的软件系统或子系统,它为一组系统或 子系统定义了架构,并提供了构造系统的基本构造块,还为实现特定功能定义了可调整点。在面向对象环境中,框架由抽象类和具体类组成。(A framework is a partially complete software (sub-) system that is intended to be instantiated. It defines the architecture for a family of (sub-) systems and provides the basic building blocks to create them. It also defines the places where adaptations for specific functionality should be made. In an object-oriented environment a framework consists of abstract and concrete classes.)
相比之下,Erich Gamma等人在《设计模式》中为框架所下的定义则循循善诱,符合面向对象开发者的口味:
(框架是)一组相互协作的类,形成某类软件的一个可复用设计。框架将设计划分为一组抽象类,并定义它们各自的责任和相互之间的协作,以此来指导体系结构级的设计。开发者通过继承框架类中的类和组合其实例来定制该框架以生成特定的应用。
2.3.2 架构和框架的区别
笔者发现,人们对软件架构存在非常多的误解,其中一个最为普遍的误解就是:将架构(Architecture)和框架(Framework)混为一谈。
一图胜千言,图2-9切中肯綮地点出了架构和框架的区别。一句话,框架是软件,架构不是软件。
框架是一种特殊的软件,它并不能提供完整无缺的解决方案,而是为你构建解决方案提供良好的基础。框架是半成品。典型地,框架是系统或子系统的半成品;框架中的服务可以被最终应用系统直接调用,而框架中的扩展点是供应用开发人员定制的“可变化点”。
图2-9 架构和框架的区别
软件架构不是软件,而是关于软件如何设计的重要决策。软件架构决策涉及到如何将软件系统分解成不同的部分、各部分之间的静态结构关系和动态交互关系等。经过完整的开发过程之后,这些架构决策将体现在最终开发出的软件系统中;当然,引入软件框架之后,整个开发过程变成了“分两步走”,而架构决策往往会体现在框架之中。或许,人们常把架构和框架混为一谈的原因就在于此吧!
我们不能指着某些代码,说这就是软件架构,因为软件架构是比具体代码高一个抽象层次的概念。架构势必被代码所体现和遵循,但任何一段具体的代码都代表不了架构。
2.3.3 架构和框架的联系
框架技术和架构技术的出现,都是为了解决软件系统日益复杂所带来的 困难而采取“分而治之”思维的结果——先大局后局部,就出现了架构;先通用后专用,就出现了框架。图2-10很好地揭示了这一点。架构是问题的抽象解决方案,它关注大局而忽略细节;而框架是通用半成品,还必须根据具体需求进一步定制开发才能变成应用系统。
图2-10 框架和架构的关系
简而言之,框架和架构的关系可以总结为两句话:(1)为了尽早验证架构设计,或者出于支持产品线开发的目的,可以将关键的通用机制甚至整个架构以框架的方式进行实现;(2)业界(及公司内部)可能存在大量可供重用的框架,这些框架或者已经实现了软件架构所需的重要架构机制,或者为未来系统的某个子系统提供了可扩展的半成品,所以最终的软件架构可以借助这些框架来构造。
2.3.4 框架也有架构
框架作为软件系统或子系统的半成品,其设计开发过程从总体上来说和系统开发非常类似(是刻意做成“半成品”的,而不是“还没有做完”),框架也是通过架构设计、详细设计、实现和测试开发出来的。当采用面向对象技术时,框架是一组类和接口,当然还可以包含资源文件和配置文件等等。框架可以很复杂,可以包含成百上千个类,可以划分模块和子系统。
总之,框架也有架构。图2-9所示的类图,其语义也表明了这一点。
3 软件架构的作用
3.1 充分发挥软件架构的作用
软件架构是软件开发过程初期的产物,但是,为了充分发挥软件架构的作用,应进一步认识到以下两点:
l 软件架构对后期的软件维护,乃至改动力度比较大的软件升级都起着重要作用;
l 越来越多的公司和企业开始注重产品线的开发,这是需要为整个产品线设计软件架构,这和为单个产品设计软件架构有很大的不同。
图3-1 软件架构的作用
从时间上来讲,产品线架构设计和单个产品架构设计发生在过程早期,而基于架构的软件维护和架构重构则发生在过程后期。如果有产品线架构的话,单个产品架构设计要在产品线架构设计之后完成,因为此时每个产品的设计都应在遵循整个产品线架构设计的基础上引入个性化的设计。
当软件系统交付上线之后,还需要不断的对它进行维护,于是有一天,当我们碰到下列两种情况中的一种时,我们下决心要将架构进行重构以使它更加合理清晰:
l 架构太混乱了,以致进行一个小修改都会牵动全身;
l 将要进行的软件升级力度很大,原先的架构已不再适应新需求了。
于是这时,我们就会对软件架构进行比较大的修改和调整,使它适应新需求以及开发和维护的需要。
从难度上来讲,产品线架购设计是最难的,因为它要考虑更多企业发展因素,引入更多变化的支持。比较而言,基于架构的软件维护相对容易些。
3.2 软件架构对新产品开发的作用
软件架构设计为什么这么难?因为它是跨越现实世界与计算机世界之间鸿沟的一座桥。
从面向业务的需求,到最终的面向技术的软件系统,要跨越很大的鸿沟。软件架构设计就是要完成从面向业务到面向技术的转换,在鸿沟上架起一座桥梁。软件架构师根据各种需求进行架构设计,最终的软件架构包括了结构、协作和技术等方面的重要决策,为系统化的开发活动建立了基础。
具体而言,软件架构对新产品开发的作用包括以下几个方面。
l 上承业务目标:不能为用户和客户实现特定目标的软件系统是没有生命力的,而软件架构设计担负着为完成业务目标而进行大局规划的职责。软件架构的黑色及必须满足用户或客户的业务目标、业务功能、约束限制和质量属性等方面的需求。
l 下接控制技术:软件开发最终生产出可运行的软件系统,它是面向技术的。软件架构师将面向业务的需求转化为面向技术的软件架构设计方案,为后面的技术开发工作提供切实的指导与限制。
l 控制复杂性:一股脑地将复杂性统统展开,就会使软件开发陷入混乱和无法控制中。现进行软件架构设计,后进行详细设计和编码实现,运用了“基于问题深度分而治之”的理念,利用控制复杂性。正因为如此,更多的人能够理解将要开发的软件系统,使开发人员、管理人员、用户和客户等都理解他们要参与的工作,并成为他们开展交流的基础。
l 组织开发。软件架构为开展系统化的团队开发奠定了基础,它规定了软件系统的各元素如何彼此相关的设计决策,从而可以把不同模块分配给不同小组分头并行开发,而软件架构设计方案在这些小组中间扮演了“桥梁”和“合作契约”的作用。每个小组的工作覆盖了“整个问题的一部分”,各个小组之间可以互相独立进行并行工作。
l 利用迭代开发和增量交付。早交付、多反馈,是提交客户满意度的最佳实践之一。以架构为中心来进行软件开发,为增量交付提供了良好的基础。这是因为性能、可测试性和可扩展性等大多数非功能需求更大程度上依赖于软件架构的设计,所以在软件架构设计方案进行验证之后,我们就可以专注于功能的增量提交,进行迭代式的软件开发。
l 提高质量。这一点可以认为是“控制复杂性”和“利用增量开发”的衍生优点。清晰的软件架构将各个模块的职责划分的有条不紊,每个模块都有清晰的接口,这相当于间接降低了开发难度,利于提交软件质量。另一方面,以架构为中心的增量开发会不断的发布软件系统的可执行版本,最初的版本所包含的业务功能并不多,这时可以重点测试软件架构对质量属性需求的满足程度,并及早做出架构调整。这显然也利于提高软件质量。
3.3 软件架构对软件产品线开发的作用
软件产品线是指具有一组可管理的公共特性的软件密集性系统的集合,这些系统满足特定市场或任务需求,并且按预定义的方式从一个公共核心资产集开发得到。
软件产品线生产的每个产品都是由来自公共资产库中的组件(Component)组成,然后按预定义的变化机制,如参数化或继承,对这些组件进行必要的剪 裁,添加必须的新组件,根据一个产品线范围内的公共架构来组装这些组件。因此,构建一个具体软件产品(应用系统)的主要工作是组装或繁衍而不是创造;主要 的活动是集成而不是编程。
产品线的内容包括三大基本活动:核心资产开发(Core Asset Development)、产品开发(Product Development)和技术组织管理(Management),核心资产的开发也称为领域工程(Domain Engineering),利用核心资产进行的产品开发又被称为应用工程(Application Engineering)。
软件产品线架构是指针对一个公司或组织内的一系列产品而设计的通用架构。
在实践中,软件产品线架构除了定义组成产品的各个部分的职责以及它们之间的交互之外,还往往:
l 将系列产品共用的模块事先实现,供直接重用;
l 有时还将架构黑色及方案用框架的形式予以实现,供定制使用。
此时,软件产品线夹头就有了一个流行的名字:平台。
产品线架构和单个产品架构的区别在哪呢?《软件产品线实践与模式》归纳了三点:
l 产品线架构必须考虑一系列明确许可的变化
l 产品线架构一定要文档化;
l 必须提供“产品创建者指南”,描述架构的实例化过程
构成软件产品线的不同产品可能是针对不同的客户、竞争者或使用环境退出的,这意味着它们是同时存在的,但他们在功能、质量属性、目标平台、所用中间件和规模等方面都可能有所不同。
软件架构对软件产品线开发的作用在于:
l 固化核心知识;
l 提供可重用资产;
l 缩短推出产品的周期;
l 降低开发和维护成本;
l 提高产品质量;
l 支持批量定制。