12 å, 2005

软件架构训练基础教程(转载自天极网)

1. 导语

本文是软件架构的基础训练,它介绍了有效的软件架构所需要的基本工具。在军事中,基础训练用于挑战和激发军官学校学生,并示范军事生涯的要求和奖赏。同样地,软件架构必须由个人来推动,这些人必须渴望对抗软件开发工作中的技术领先阶层的挑战。但是,这样的动机还是不够的。软件架构必须等同于认识架构全景的智力手段。  本文提供了一条便利的方法,它不仅显示了行业中最好的架构经验,还提供了具体的现实例子和练习,以便把它提供的素材应用于整个软件行业的普通环境中。

1. 导语

本文是软件架构的基础训练,它介绍了有效的软件架构所需要的基本工具。在军事中,基础训练用于挑战和激发军官学校学生,并示范军事生涯的要求和奖赏。同样地,软件架构必须由个人来推动,这些人必须渴望对抗软件开发工作中的技术领先阶层的挑战。但是,这样的动机还是不够的。软件架构必须等同于认识架构全景的智力手段。  本文提供了一条便利的方法,它不仅显示了行业中最好的架构经验,还提供了具体的现实例子和练习,以便把它提供的素材应用于整个软件行业的普通环境中。基本训练覆盖了软件技术的基本概念,它提供了软件架构的基础。软件技术已经向软件开发的很多趋势和可选的方法不断演化。目前,主流的软件实践从面向过程演化到面向对象,然后又演化到面向组件的开发(图1)。

随着企业级Java和微软.Net不断采用,面向组件将成为下一个主要的范式。在共同开发中,大多数新开始的项目都采用了面向组件技术,因为它受到了多数商业开发环境的支持。本文的前面提到,面向对象的软件架构观念非常薄弱,这导致了一些严重的缺陷。正在形成中的面向组件的趋势正在利用架构设计的强大原理代替旧的方法。 软件架构必须能够清晰地描述这些开发范式,同时允许技术适当地使用。在任何给定的项目中,折衷的混合的开发范式(包括关系数据库管理)对于获得最佳结果都是有用的。每个技术都提供了一些优点,包括成熟的开发工具。  目前大多数组织会发现它们的技术技巧基于正在使用的三种主要的技术之一:面向过程的、面向对象的或面向组件的。每个范式对于某个组织和它全部职员的技能都是非常明确的。面向过程和面向对象的范式都被编程语言的选择紧紧地约束了,但是面向组件就不同了,它与下层构造的选择的关系更加紧密。  面向过程的编程语言包括FORTRAN、COBOL、C、Pascal和BASIC。在面向过程的技术中,程序由执行不同算法的过程组成。过程与系统中的数据是分离的,而且过程通过直接访问操作(access operations)使用数据。这是存储过程编程系统的直接后果,而计算机技术就源于此。当程序和数据分离时,在程序的各部分之间存在很多潜在的内部依赖性。如果数据表现被改变了,程序的多个位置都可能受到冲击。  数据-过程分离的一个例子是2000年问题,在这个例子中简单地给日期表现添加一些数字会对面向过程的软件产生灾难性的后果。不幸的是,因为主流的系统都是使用面向过程的技术建立的,对这些数据表现的依赖可能会引起系统范围的程序错误,并引起了逐行检查、修改程序的必要性。

2. 面向对象技术

面向对象编程语言包括Smalltalk、 C++、 Java编程语言和C#(微软.Net开发环境中提供的一种语言)。这些语言按照抽象数据类型(通常称为类)的要求支持数据和操作代码的封装。在面向对象编程语言中,封装能力对于适度大小的程序是足够的。只要软件模块由单独的程序员维护,封装对于提供一些内在的优点就是完全足够的。但是,特定语言的封装不足以支持软件的重复使用和分布式系统。  在面向对象技术中,基本范例被改变为允许关系的分离。图1显示了面向对象技术的范式,在它里面程序被分成叫做对象(object)的更小的片段。每个对象都包含了系统的一些数据,并且程序封装了这些数据。换句话说,只有通过使用与该数据直接相关的程序才能访问这些数据。通过这种方法,系统被分离成独立改变的模块。数据表现的任何改变仅仅影响封装该数据的直接的对象。  对象使用消息彼此通讯。消息可能影响状态——换句话说就是改变数据——但是只能通过与本地数据密切相关的封装了的过程来改变它。对于小程序,对象范式对于隔离改变来说是有效的。但是,这个范式对于所有可能的使用情形来说并不是完美的。  现在面向对象技术已经被广泛地使用了。一般来说程序上的技术来自于学术界,但是面向对象技术事实上来自于商业组织。实际上面向对象技术有很多有趣的渊源,甚至于可以追溯到计算机科学的开端。现在对象技术是占有统治地位的商业软件范式。事实上每个软件生产商都提供了对象技术的解决方案,并一起提供了组件的下部构造,允许不同软件环境中的软件厂商之间交互操作。  面向对象的架构  对于主要的软件开发从业者来说,面向对象是缺乏软件架构方法的。在面向对象的方法和文化中,这种缺乏在很多方面都有表现。从通常被当作原始来源的OO(面向对象)思考、设计面向对象软件【Wirfs-Brock 1990】开始,已经有了软件架构的概念,包括通过观察协作图(collaboration diagram,它需要一个章节才能讲清楚)发现子系统(subsystem)。在接下来的十年中,在面向对象方法学社团中几乎没有写出什么有关架构的东西。主要的OO方法学的书本中关于架构的章节都很少,它们都是Wirfs-Brock的架构概念的一些模糊的反映。  由于实际上几乎没有关于架构的专著,大多数OO从业者都只有最基础的架构指导。他们没有理由认为架构很重要。这种态度导致OO项目中很大的混乱,因为小组成员必须尽全力去管理那些并非为他们设计的OO方法的复杂性和可伸缩性。  一般而言,OO方法包含了成功的对象模型技巧,在这些模型中大多数分解对象最终被转换为编程对象。这种方法叫做基于模型(model-based)的方法。为了了解架构,认为每个分解对象都不可避免地成为编程对象是所有OO开发人员都需要克服的一个主要障碍。在架构模型中,特定对象表现约束而不是编程对象。它们可能会,也可能不会被转换成编程对象,这是由开发人员的自行的决定。   OO也在其它一些微小的地方与架构矛盾,这与项目文化相关。OO鼓励项目小组平等,这样所有的决定都是民主的。在这样的项目中就没有架构的角色了,因为在开发小组的成员之间作出的决定的差别是很小的。   OO鼓励开发中的“bad-is-better”思考方式,实际上这是一种与架构思想背离的哲学。使用bad-is-better思想的时候,任务实现的外部表现远远超过了可以维护的的内部结构的任何需求。换句话说,快速迭代的原型处理,以及对架构原理的无情的漠视对于OO开发来说是一种正常的、健康的环境。  架构的话题只在最近的OO专著中与新发现的组件技术一起被重新提到的。现在大多数方法学的书本都习惯性地包含一个关于架构的象征性的章节,但是在OO的全盛时期,架构实际上是禁止使用的。从感觉上讲,组件是OO的缺点的反映。组件的强调较大“颗粒”的软件接口和模块,是向架构想法方向的改进步骤。  数据库和对象   数据库技术也朝对象的方向演化。数据库技术源于几个不同的模型。近些年,数据库的关系模型是最有影响力的。到最近,面向对象的数据库已经成为重要的技术市场,而联合了面向对象和关系概念的数据库也很平常。大多数主要的行业数据库,例如Oracle 9i和IBM的DB2数据库都包含了对象-关系能力。  数据库查询语言,例如结构化查询语言(SQL),都在标准的工作方面进行了扩展以支持面向对象的概念。发生这种情况的原因之一是人们正在建立的这类应用程序需要充分的、更多的适合显示需要的数据表现类型和查询算法类型以搜索和维护信息。  对象在主流技术中的地位   目前对象技术应用于大多数应用程序范围和垂直的市场中。政府组织和工商企业正在用对象技术运作大量的项目。对象技术的主要优点是它允许为组织提供竞争优势的新业务流程的实现。社会正在朝不断依赖信息技术的方向转变。对象技术的使用通过软件重复使用机制允许快速的系统实现和各种形式的劳动力的节省。尽管大量的软件代码仍然存在于面向过程的语言(例如COBOL)中,但是很清楚这种范式正在改变。  脚本语言   脚本语言的支持者声称使用脚本语言的编程人数比使用其它类型语言的编程人数都要多【Ousterhout 1998】。脚本语言,例如JavaScript语言、TCL shell编程语言和Visual Basic语序可以把先前存在的软件(例如组件)轻易地集成到应用程序构造中去。

3. 面向组件技术

在上篇文章中,我们介绍了《面向对象的软件技术》,面向对象技术催生了组件技术,组件技术为软件开发提供了改良的方法,它向过时的设想提出了挑战。这些原理共同建立了一种主要的新的技术趋势。组件表现为技术变革的基础,就像面向对象先前表现出的一样。我们在简短地介绍组件的独特原理后再讨论组件技术。  迁移到下一个层次的软件技巧要求系统思想、软件处理和技术工具的基本原理都有所改变。下一个主要的技术范围——组件(或面向组件)包含了解决目前危急的软件问题的关键的原理。     组件的方法引入了一套紧密相关的技巧和工艺。组件技术引入了用于生成业务结果的一套改进的想法。为了产生业务效果,组件引入了一个技巧性的想法。这些组件原理包括:  组件的下层构造  软件模式  软件架构  基于组件的开发   组件与对象的对比   组件可以被认为是面向对象和其它软件技术的化身。区分组件和其它先前的技术有四个原则:封装(encapsulation)、多态性(polymorphism)、后期连接(late binding)和安全性(safety)。这个列表与面向对象是重复的,除了它删除了继承(inheritance)这个重点。在组件思想中,继承是紧密耦合的、白盒(white-box)关系,它对于大多数形式的包装和重复使用都是不适合的。作为代替,组件通过调用其它的对象和组件重复使用功能,代替了从它们那儿继承。在组件术语中,这些调用叫做委托(delegations)。  把各部分装配在一起,一个放在另一个里面,像木匠修建房屋一样建立你自己的轮廓。每样东西都必须建造好,各部分组合在一起就形成了全部…”——Henri Matisse  根据惯例,所有组件都拥有与它们的实现对应的规范。这种规范定义了组件的封装(例如它为其它组件提供的公共接口)。组件规范的重复使用是多态性的一种形式,它受到高度鼓励。理想情形是,组件规范是本地的或全局的标准,它在系统、企业或行业中被广泛地重复使用。  组件利用合成(composition)来建立系统。在合成中,两个或多个组件集成到一起以建立一个更大的实体,而它可能是一个新组件、组件框架或整个系统。合成是组件的集成。结合的组件从要素组件中得到了联合的规范。  如果组件符合了客户端调用和服务的规范,那么它们不需要额外编写代码就能够实现交互操作(interoperate)。这一般被称为即插即用(plug-and-play)集成。在运行时间执行的时候,这是后期连接的一种形似。例如,某个客户端组件可以通过在线目录发现组件服务器(类似CORBA Trader服务)。组件符合客户端和服务接口规范后,就能够建立彼此之间的运行时绑定,并通过组件的下部构造无缝地交互作用。  在完美的情形中,所有组件都将完全符合它们的规范,并且从所有的缺陷中解放了出来。组件的成功的运行和交互操作依赖于很多内部和外部因素。安全性(Safety)属性可能是有用的,因为它可以最小化某个组件环境中的全部类的缺陷。随着社会日益依赖于软件技术,安全性已经成为一种重要的法定利害关系,并成为计算机科学研究中的最重要的课题之一。例如,Java的垃圾收集(garbage collection)特性保证了内存的安全性,或者说从内存分配缺陷(在C++程序中这是有问题的)中解放出来了。其它类型的安全性包括类型安全性(type safety,用于保证数据类型的兼容性)和模块安全性,它控制着软件扩展和组件合成的效果。

组件的下部构造   组件革命已经发展到组件下部构造的形式上了。主要的平台厂商都把自己的未来寄托在组件产品线上。特别地,微软、SunIBMCORBA社团都已经通过大量的技术和市场投资建立了重要的组件下部构造。  这些组件下部构造(微软的.NetSunJava Enterprise JavaBeans包含了CORBA)都是与行业中面向对象的企业应用程序开发部分竞争的主要的下部构造。有趣的是,这些技术通过共同支持的XMLWeb服务和其它企业应用程序开发的标准把互相之间的交互操作进行了很大的扩充。  微软在当前的.Net产品套件中完全修复了自己的组件下部构造。微软.Net产品套件聚焦于企业级应用程序和分布式服务的开发和布署。尽管它混合了大量的新代码,但是它也包含了微软前期的分布式开发平台——微软分布式网络架构(DNA)和类似微软事务处理服务器(MTS)、微软SQL Server等分布式通用对象模型(DCOM)和长期存在的通用对象模型(COM/COM——的很多成功的产品和技术。已有的.Net套件在集成的企业产品套件中更新了这些产品,增加了对XML数据、Web服务和大量改善的开发环境的新的支持。微软.Net是软件行业需要验证的有形证据,证明微软在可以预见的未来的正在形成的组件世界中将扮演主要角色。  Sun公司发明的Java语言是编程语言特性、下部构造和相关的类库的持续的演化。Java语言技术引起了行业极大的骚动,并受到独立开发者的支持。Java-Beans Enterprise JavaBeans的扩展建立了一种进化的组件模型,它可以在跨平台的应用范围之中与COMActiveX竞争。Enterprise JavaBeansIBMSan Francisco项目正在使用Java远程方法调用(RMI)做分布式计算,它是Java语言程序员可以使用的几个专利下部构造之一。最近,Java语言已经在OMGInternet内部ORB协议(Internet Inter ORB Protocol IIOP)之上包含了RMI,它允许Java与其它拥有CORBA IDL接口的编程语言中的分布式组件交互操作。尽管专利Java语言下部构造的确为程序员提供了便利,但是为了与其它编程语言之间交互操作,它们需要额外的复杂性,特别是在局部使用Java本地接口(JNI)调用Java之外的编程语言中的程序的情形中。这对于共同的项目有重大的障碍,因为它减慢了传统技术的集成和跨语言的开发,而这些对于服务器应用程序是很常见的。  在很多了解Internet的组织中Java应用程序服务器已经取代了CORBA的角色。CORBA缺乏的是对可伸缩性、可靠性和可维护性的直接的支持。现在这些能力都是大多数Java应用程序服务器支持的标准特征了。  组件的下部构造对于软件开发有重要的影响。在很多方面,这些下部构造正在向成为主流开发平台的方向前进。因为它们都变成了可以交互操作的(通过CORBA IIOP),下部构造模型之间的关系都很好理解了。它们的相似点远远大于它们的专利的差异。  下部构造的选择是讨论得最多的一个问题,但是对于组件的实现而言,其重要性却最低。对于共同开发者来说,最重要的问题会在选择下部构造之后遇到。这些问题包括如何掌握使用这种技术进行设计、如何架构系统、如何协调彼此之间的开发工作。
  组件软件的设计模式   软件设计模式由能够应用于所有组件下部构造的软件知识的共同主体组成。软件设计模式是检验过的用于解决特定类别的结构上的软件问题的设计方法,它们已经备案以供其它开发者重复使用。其它重要的模式类别还包括分析模式和AntiPatterns。分析模式定义了对业务信息进行建模的检验过的方法,它可以直接应用于新软件系统和数据库的建模。  软件设计模式是组件的一个必要的元素。新的、可以重复使用的组件的开发要求的设计、规范和实现都有专家级的质量。经过检验的设计方案对于建立成功的应用程序系列的组件架构和框架是有必要的。通常,在没有检验过的设计观念中偶然性变数太多了。  软件设计模式的流行可以看作是对面向对象在实践中的缺点的反映。AntiPatterns解释了人们开发面向对象软件系统(以及其它类型的系统)的时候通常犯的错误。想要建立成功的系统不仅需要基础的面向对象的原理。设计模式解释了有效的软件设计所需要的额外的、改善的想法。分析模式提出了概念和数据的有效建模所必须包含的改善的想法。  在软件开发中彻底改造设计思想仍然是很普遍的,这导致了试验-错误实验法的风险和延迟。实际上,大多数软件方法鼓励彻底地改造,把它作为开发的一般模式。给定了需求的改变、技术革新和分布式计算的挑战压力之后,彻底改造对于很多环境都是不必要的风险。这种意见特别适用于组件的开发,在这种情形中缺陷和重新设计的代价可能影响多个系统。  总而言之,软件设计模式可以用知识的重复使用(knowledge reuse)来描述。有趣的是大多数模式都被认为像专家级开发者的常识一样简单。但是,对于大多数开发者来说,模式是技术训练中必要的部分,它可以帮助开发者获得世界级的结果。
  组件软件的架构   软件的架构涉及到从早期的系统概念到开发和操作范围内的系统结构的计划和维护。好的架构是稳定的系统结构,它可以适应需求和技术的改变。好的架构确保了系统的生命周期中人们需求(例如质量)的持续的满意度。可以重复使用的组件是良好的架构的例子。它们支持稳定的接口规范,可以适应改变,是在很多系统环境中重复使用的结果。  软件架构在组件的设计、规范和使用中扮演着重要角色。软件的架构提供了组件设计和重复使用的设计环境。组件在软件架构的预定义方面扮演一定的角色。例如,组件框架就可能预定义了系统的某个重要部分的架构。  组件的软件架构的最令人兴奋的方面之一是支持分布式项目小组。软件的架构包含一个系统规范,它允许系统或系统的部分并行地、独立的开发。适当的软件架构定义了计算的边界(例如API),它把系统分成独立的可以测试的子系统。这些子系统可能被一个或多个分布式项目小组所采用。

4. 4. 技术所有权

由于对象技术是占有统治地位的商业范式,所以我们了解可用于软件系统架构的主要的商业技术是很重要的。其中主要的两类包括专利软件和开放系统软件。
  专利软件   专利软件(Proprietary software)是单个厂商的非兼容标准的产品。该厂商控制了多个重复的产品版本中的软件的形式和功能。目前的系统在建立的时候,它们在很高程度上依赖于商业软件。商业软件是软件重复使用的主要的形式,并且实际上它是单个企业中的一种更加高效的重复使用的形式。  因经营规模的扩大而得到经济节约是商业软件成为更加强大的重复使用的形式的一个原因。软件的大量副本被分发给客户,并且软件的除错和质量控制的程度远远超过了即使最大的终端用户企业的内部开发能力。当终端用户企业依赖于专利软件的时候,他们都是依赖于该厂商对于已有能力的持续的支持,并且从结构上说,很多终端用户依赖的厂商主张的很多的未来特性都将被添加到软件中。当专利软件以公共规范或标准的形式包装的时候,该规范通常成为单个软件实现的直接表现。  通常,当专利规范进入到公共领域的时候,这种专利实现一般不会被改变。当实际上没有必要修改下层技术的时候,它留下的印象是专利软件也可能成为一种开放系统的标准。当成千上万的软件许可被分发并且在已有的软件系统上运行的时候,这种现象特别真实。当专利技术向前发展的时候,厂商使用软件概念的唯一的解释来描述它们的产品。这种解释可能包括对面向对象原则的基本原理的修改。  我们规定建筑物的形状;从那以后建筑物就规定了我们的形式。”——Sir Winston Spencer Churchill  专利技术的最重要的方面是应用程序接口(API)的规定。专利软件的API定义了某种专利实现与增值应用软件(可能是独立软件厂商或最终用户提供建立的系统)之间的边界。随着专利软件技术通过多种方式演化,应用程序编程接口也可能改变。  新的能力仍然在持续不断地添加到专利软件中,这加剧了应用程序编程接口的复杂性。在很多情形中,专利软件的编程接口的复杂性远远超过了最终用户组织需要的功能。接着最终用户组织试图用多种方式管理这种复杂性就变为合适的了。  作为给专利编程接口增加新能力的补充,厂商有时可能会废弃软件中的一些接口。这样做会对应用软件产生重大的维护方面的影响。随着专利软件通过多种方式的演化,持续地升级软件以保持与专利厂商提供的主流支持活动同步,这一点对于用户很重要。当最终用户的系统落后了两个以上周期的时候,通常必须重新购买或完全重新修复该商业软件,这样才能与当前版本同步。很多最终用户发现在产品版本的少数周期中应用程序接口几乎全部是废弃的。  总之,专利软件版本和编程接口的演化成为应用程序开发人员和独立的软件厂商为了保持与可以使用的和受到支持的软件同步的单调的工作。这是应用程序用户和专利软件厂商之间的冲突,因为厂商利润的大部分可能由软件升级包的销售来驱动。

开放系统软件   另一类主要的商业软件是开放系统技术(图1)。从本质上说开放系统技术与专利技术是不同的。在开放系统技术中,多个厂商达成一致的规范,而这种规范不依赖于专利实现。这就是大多数正式的标准活动和多数社团标准活动的情形,它正在变得更加流行。在开放系统技术中,各种规范都支配着实现的行为。

1.专利技术(a)和开放系统技术 (b)

  它的关键的好处是多个厂商的实现接口的一致性。其它的优点还有术语和软件接口的一致,这是因为开放系统技术要求多个厂商达成一致。另一个优点是技术规范水平的增强和生命周期的延长。由于产品的开发是通过多个厂商组织并行进行的,引发市场需求的相应市场活动也是同步的和协调的。开放系统技术关键的优点之一是它提供了商业软件厂商之间的互通性。开放式系统和专利技术之间的差异对于面向对象的系统尤其明显,而它正在成为应用程序开发的主流,因为对象技术已经成为商业技术的主流。  商业信息技术一直在演化。日益满足应用程序需求的额外能力正在添加进来,并且通过商业技术逐渐可以使用了。但是在基础能力的商业技术(例如操作系统和编程语言)方面仍然需要大量的彻底的改造。  在有些商业技术(例如办公自动化、字处理和电子表格)中,很多功能被持续不断地重新组织并提供给最终用户,却没有显著的性能扩充。在很多人看来,商业端的技术演化的速度相对于竞争性的应用程序开发者的需求的增长较慢。商业技术的发布是为了满足大量用户的需求。这种软件的一般性超越了任何个别应用程序用户的需求。为了改变商业技术以满足应用程序的需求,就需要软件的配置和安装,它定制商业软件以适合特定应用程序的需要(图2)。

2.商业软件的定制

  定制商业技术的需求通常称为profiling。作为定制软件的补充,我们需要用牢固的特定应用软件来建立应用系统。因为对于多数应用需求来说,商业上可以使用的能力相对原始,所以这种需求驱动着一种不断增长的需求——建立越来越多的特定应用软件来完善应用系统的架构。随着系统从单用户演化到部门级再演化到企业级应用程序,其互通性也更强,可供使用的商业软和单独的用户软件之间的功能差异还会不断增加。  应用软件系统的架构在系统如何支持用户需求方面显得日益重要。电信行业之外的多数系统都是使用面向过程或其它的范式集成的,而这样做通常会造成无效的解决方案。实际上,对于共同开发组织建立的系统来说,大多数软件项目在完成时就被认为是失败的。从架构的观点来看,其中很多系统都类似于图3a)中stovepipe系统中的构造。在stovepipe系统中有大量集成的软件模块,每个软件模块都有独特的软件接口,这些独特的软件接口分别与一种程序的实现相对应。

3. Stovepipe系统(a)和组件架构(b

  系统集成的时候,它的不同部分之间存在很多一对一的依赖关系。这些依赖关系都是独特的集成方案。伴随着系统的大小随着模块数量不断增长,依赖关系的数量按模块数量的平方增长。这样的复杂性的增加带来了很多负面效果。特别是,随着系统的演化,修改和扩展变得越来越困难了。系统扩展恰恰是应用程序开发中的主要的成本驱动因素;它大约占了所有软件成本的一半【Horowitz 1993】。  建立系统的可选的方法之一是包含计划好的软件接口的定义,由它提供跨越集成方案的更高层次的一致性。组件架构是一种使用了一致的应用程序编程接口、跨越多个软件子系统实例所定义的应用系统(图4)。组件架构减少了软件模块之间的依赖关系,而依赖关系的减少使系统可以扩展,并且支持更大规模的集成。适当地建立的组件系统的软件集成的复杂性依赖于建立该系统所需要的软件模块的数量。

最新回复
发表评论













Bold Italic Link