利用软件工厂和 Visual Studio Team System 度量成功(转帖)

利用软件工厂和 Visual Studio Team System 度量成功

发布日期: 2006-11-29 | 更新日期: 2006-11-29

Marcel de Vries

Info Support

Jack Greenfield

Microsoft Corporation

适用于:

Microsoft Visual Studio Team System

Microsoft SQL Server 2005 Reporting Services

软件工厂

摘要:本白皮书讨论了如何将软件工厂和 Microsoft Visual Studio Team System 配合使用来改进质量、可预见性和生产力。通过利用 Visual Studio Team System 的数据仓库和报告功能,软件工厂生成器能够可靠地确定产品开发的哪些方面需要改进以及如何修改软件工厂才能改进这些方面。

本白皮书最终得出的结论是,可借助软件工厂方式而非传统的一次性开发来改进质量、可预见性和生产力。本文所涉及的概念和工作方法面向的是开发自定义软件的系统集成商及企业客户。

*
本页内容
简介简介
改变构建软件的方式改变构建软件的方式
度量质量和生产力度量质量和生产力
应用 Visual Studio Team System应用 Visual Studio Team System
使用度量构造 (ISO 15939)使用度量构造 (ISO 15939)
综合利用综合利用
结论结论
参考资料参考资料

简介

如今构建软件已成为一项艰巨的任务。系统变得日益复杂而庞大。我们不但要面对瞬息万变的技术,同时又要设法与那些希望我们以更高质量和速度编写更多软件的业务客户的需求保持同步。既要提高软件产量,又要保证其质量有所改进,这真的可能实现吗?是否能够既保持整个维护和升级过程中的较高生产力,而又不会以牺牲质量或大量重写代码为代价?拥有数百万行代码的系统不太可能进行重写,尤其在业务需要快速完成变更时更是如此。在本白皮书中,我们将阐述如何通过在软件开发中采用软件工厂方式来提高生产力和软件质量。

改变构建软件的方式

数十年来,软件业已打造出多个软件系统来满足其客户的需要。即使拥有所有这些开发经验,软件质量和生产力却未能随之快速提高。根据 Standish Group 所进行的一项年度调查,我们发现我们现今的生产力水平与 10 年前几乎没有什么分别。目前,在所有软件开发项目中,有 54% 的项目在超出预算的情况下交付,66% 的项目未得到其客户认可,90% 的项目无法按时交付!但该调查所揭示的最令人烦忧的一点是,这些数字在过去的十年里一直都没有多少改观。

召集一组开发人员或项目经理,当面问他们,是否觉得自己如今在构建软件领域做得比较成功。多数人在这时往往是置之一笑,同时承认他们也是这种结果的牺牲者。令人遗憾的是,我们往往认为,由于构建软件是一个极具创造性的过程,因此我们必须要容忍糟糕的交付项目。

目前构建软件的方式

生产力低下通常是由于未能正确了解需求或未能全面了解需求而造成。不止是构建不适合的系统会导致生产力严重下降,当项目范围在逐渐扩大,导致其超出最初的功能量时也会导致生产力严重下降。我们还发现,要达到令人满意的测试水平以确保预期的质量水平是很困难的。不成功的维护和升级发布通常与无法预见到代码更改对产品质量的影响有关。我们该如何确保对系统某一部分的更改不会破坏另一部分呢?

由于我们很少从曾经完成的项目中吸取教训,因此导致这类问题频繁出现。当问到开发团队他们是否从自己的错误中吸取了教训时,明显会看到几乎没有人会主动积极地去总结教训,并将其应用到以后的项目中。很少有团队会习惯性地重新使用过去创建的解决方案,或者对成功和失败的案例进行记录。结果是,没有充足的知识和信息在各项目之间传递,各开发人员所了解的知识和信息依旧停滞在自己的脑海里。新的开发人员需要重蹈覆辙才能获得以前的开发人员本来已经吸取的经验和教训。开发人员发现很难以脱离现有的项目,因为他们对这些项目太熟悉了,并且发现加入新项目也很难,因为没有留下什么记录可供参考。

由于多数项目都无法按时交付且会超出预算,因此我们意识到,我们还要面对一个可预见性问题。当问到项目经理是如何制定计划和日程表时,可以更明显地看到,许多人都在恪守着旧习惯,他们往往会这样说:“我向我最出色的程序员询问了此功能估计要花费多少时间,然后我会将该估计结果增加一倍;我的程序员往往都比较乐观。”通常,这种“预算”之后就会被缩减,或者是为了交出一份有竞争力的投标条件,使这些数字带来好结果,或者是为了满足预期要求。这些旧习惯是很难以改变的。

但老实说,项目经理几乎要注定依赖专业人员来推测,因为他们没有可靠的量度来代替使用。他们需要能够以一种可靠的方式从软件开发项目收集量度,例如,通过数据仓库。从这些量度中,他们可以了解到其开发团队的运作情况,并利用了解的知识和信息来构想出更准确的估计数据。利用历史数据来对组织或项目绩效进行标准化可以提高估计数据的准确度,但多数估计数据并不是这样得出的。

如果没有良好的可预见性,是很难以掌控项目的。在项目经理进行决策时,如何才能了解这个决策将对其日程表和成本带来什么影响?您不能只是用粗略的估计数据来预测所做决策的影响。这与蒙着双眼射击又希望射中目标并无两异。

这些问题就是我们花费大量时间却生产出很少软件的原因。我们交付的软件质量拙劣且难以控制。要使开发过程尽在掌握之中,我们面临着重重困难。对于实践者来说,很难以对项目进行变更。超出预算的每个小时都会产生额外成本,在测试中(甚至更严重的是在生产中)发现的每个缺陷还要花费更多成本,这与整个过程中做出的每个错误决策的结果是一样的。如今构建软件的代价是非常昂贵的。

使用软件工厂

我们能改善这种情况吗?答案是肯定的。我们能够在构建软件时保证其准时交付、不超出预算并且质量达标。不过,首先各组织必须先意识到当前构建软件的方式是非常低效的。如果意识不到问题的存在,也不会有改进的动力。要在保证可预知性的前提下开始构建软件系统,我们必须进行一次文化变革。我们必须使实践者更容易地了解要执行任务的内容、执行时间、执行原因以及执行方式,并且必须将其工作中更多的机械和/或琐碎的方面实现自动化。可通过将开发流程中选出的各方面进行形式化来达到这些目标。这些方面有哪些?我们该如何将它们形式化而又不失灵活性?

创造性和形式性

关键是将那些创建和修改工作产品的精细活动进行形式化,而不是设法形式化整个开发流程。粗放式工作流随后可根据项目要求和情况来逐渐演化,前提是要一直保持固定流程以确保结果有效。例如,您可以同时着手编写多个类,根据需要在它们之间进行切换,只要在您编译时它们之间的所有依存关系都得以满足。这种机动性即保持了灵活性又防止了围绕单个活动排队的情况。如果将精细活动形式化,而不是试图将整个开发流程形式化,则可以在保证质量、可预见性和生产力的同时而又不失灵活性。您会认识到哪里需要形式化,哪里不需要形式化,从而更容易在灵活性与形式性之间取得适当的平衡。通过仅在需要形式化的环节和时间实施形式化,可以使开发流程随着经验的积累以一种非常系统的自下向上的方式演化。此方法还使收集知识及信息并在各项目和实践者之间传递这些知识及信息变得更加容易,本文稍后会对此进行阐述。

解决问题时需要创造性,但执行机械和/或琐碎的活动时不需要创造性。遗憾的是,典型开发人员的日常工作中有很大一部分是由机械和/或琐碎的活动组成,但这也许不会让人感到意外。保证生产力和可预见性而又不失灵活性的关键是,在需要创造性的方面激发并支持创造性,在不需要创造性的方面则进行形式化。我们对模式、惯例和工具的形式化范围越大,从流程中剔除的不必要的变更就越多。剔除不必要的变更可以更容易地度量软件开发项目,从中吸取经验教训,并使用这些度量值来改进未来的项目。将机械和/或琐碎的活动形式化减少了在不需要创造性的活动上花费的时间和精力,从而激发了更大的创造性。

软件工厂

我们要讨论的是,将软件开发行业化,将已得到其他行业长期认可的方法应用于我们自己的行业,希望的是我们客户和我们自己的情况都能得以改善。这种行业化要通过创建可同时提高软件开发生产力和可预见性的软件工厂来实现。

软件工厂是由用于加速特定类型软件组件、应用程序或系统的生命周期任务的集成式流程、工具及其他资产组成的打包集。通过为实践者提供指南来协助他们了解要执行任务的内容、执行时间、执行原因以及执行方式,从而实现加速。为此,我们提供了将流程形式化做到恰到好处的流程指南、可快速组装和配置的组件,或可快速完成的框架,并提供了将机械和/或琐碎活动全部或局部自动化的专用工具。

我们希望借助软件工厂实现的其中一个主要目标是,从过去针对常见问题或需求创建的解决方案中学习经验和教训,然后将这些经验和教训应用于未来的项目中。为此,我们需要一种描述这些可重用解决方案的方式,还需要一种围绕相关或所关注领域(也就是经常遇到这些解决方案所解决问题或需求的领域)来组织这些解决方案的方式。按照此方式组织解决方案有助于缩小同时需要关注的问题或需求的范围,从而更轻松地确定可能适用的可重用解决方案。这些应予以关注的领域可能处于高抽象级别(例如,定义体系结构层),也可能处于低抽象级别(例如,为 C# 类或接口定义方法签名)。

架构和模板

软件工厂使用了 IEEE 1471 术语,即“对软件密集型系统体系结构描述的推荐实践”,它将关注领域称为“视点”。视点可能因多种原因而定义,例如,在软件开发生命周期的不同阶段,在不同抽象级别描述产品的不同部分。各视点是相互嵌套的,因此,“数据访问层”视点可能包含一个“数据访问库”视点、一个“逻辑数据库设计”视点、一个“物理数据库设计”视点以及一个“数据安全性”视点。

从给定视点生产或耗用的工作产品组成一个“视图”。视图由其视点定义,这与对象由其类定义差不多。工作产品可能是某个文件、某个文件的一部分、多个文件或多个文件的多个部分。例如,在“数据访问库”视点中,工作产品可以是一个包含了用于数据库表格的数据访问类的文件。由“数据访问库”视点定义的视图可以是包含一组用于给定数据库中所有表格的数据访问类的项目。视点可以交互组合,也可以呈模块化结构。例如,针对“数据安全性”视点的工作产品可能是数据访问类的插入、替换和更新方法的前导。

视点往往会推动项目类型和工具的创建。例如,“数据访问库”视点可能会映射到一个基于具有某些属性的项目模板的类库项目类型,从而包含具有数据访问类某些属性的项目模板。当我们创建该类型的项目时,就会基于该视点创建视图。视图的内容即是项目文件夹中的文件。这些是由视点定义的工作产品。

在较高的抽象级别,视点往往会推动工具的开发。例如,“业务流程”视点可能由业务流程建模工具来表现。该工具以模型的形式呈现基于该视点的视图,这些模型也就是由该视点定义的工作产品。它还通过菜单命令和其他示意动作(例如,执行从工具箱到图表的拖放操作以创建新的消息类型)来支持由视点定义的活动。

对于每个视点,都需要有一个名称和描述。我们还需要知道生产或耗用的工作产品、创建或修改这些工作产品所涉及的步骤,以及用于执行这些步骤的资产。换言之,视点应该告诉我们要构建什么、如何构建,以及可使用什么来构建(模式、工具、模板等)。视点是软件工厂的构建块。它们将那些创建和修改工作产品的精细活动进行了形式化。

每个软件工厂都定义了一组构建其产品所需的相互关联的视点。这组相互关联的视点称为“架构”。您可以将工厂架构设想为一个目录,它可帮助您发现软件工厂的组织方式,以便您可以使用它所提供的资产来构建其目标产品。工厂架构在很大程度上像是一个数据库架构,数据库架构可帮助您发现数据库的组织方式,以便您可以导航、查询并操纵其中包含的数据。但工厂架构不是描述数据的组织方式,而是描述软件工厂的组织方式。

举一个简单例子来说明架构,让我们设想一个基于“面向服务的体系结构”(SOA) 创建“企业管理应用程序”的工厂。对于该工厂,您可能要定义以下视点:

前台应用程序。描述支持用户桌面上数据输入的 Web 或 Windows 应用程序的创建。它告诉用户如何使用窗体设计器和您所开发库中的数据输入控件来创建 Web 或 Windows 窗体。用于此视点的活动是创建 Web 或 Windows 窗体。工作产品就是这些窗体。所用资产是窗体设计器和数据输入控件库。

流程服务。描述负责管理业务流程的 Web 服务的创建。Web 服务始终按照某模式以同一方式构造,并且带有一个由 C# 接口使用 XSD 架构生成的类型化对象来描述的服务合约。用于此视点的活动是创建 Web 服务。Web 服务即是工作产品。所用资产是模式和类型化对象生成器。

平台服务。描述不负责业务数据而仅负责通用于所有系统的服务(如打印、审核、授权等)的 Web 服务的创建。此视点提供了可重用的通用服务,并告诉用户如何评估和定制每个服务。用于此视点的活动是评估和定制这些服务。工作产品是定制服务。所用资产是通用服务。

最后一条要了解的软件工厂术语是工厂“模板”,它是一个包含软件工厂所提供资产的可安装数据包。要使用工厂,实践者必须将工厂模板安装到工作站上。

工厂通常是以自下向上的方式开发。确定了目标产品系列后,在构建系统时,可以开始发现并描述工作产品和活动;将它们组织到视点中;开发支持这些活动的资产;将各视点组织到工厂架构中;然后将各资产打包到工厂模板中。

功能配置

构建有效工厂的关键之一是定义可在多个不同的解决方案中付诸使用的工作产品、活动和资产。例如,“数据访问库”视点可提供有助于访问 SQL 数据库的库。您可能会发现,您并不是始终将同一个 RDBMS 用于每个项目,因此,您的库必须要容纳其他 RDBMS。与该库配合使用的工作产品和配合库执行的活动的描述可能也必须做出相应调整。视点接受的可变性越多,将其应用于多个解决方案的灵活性就越高,但同时也要执行更多的工作才能将其配置正确。允许可变性却带来了复杂性。您必须在过多可变性与过少可变性之间找到适当的平衡点,才能使软件工厂发挥效用。您的工厂的通用性越高,实现的生产力和可预见性就越低。

确定应该允许多少可变性的一个有效方法是分析您期望构建的解决方案的功能。通过利用一种称为“通用性/可变性 (C/V) 分析”的方法,您将那些必须以同一方式在每个解决方案中都出现的通用(或强制)功能与那些可能只在某些解决方案中出现的可变(或可选)功能,或在各解决方案之间出现方式不同的功能分隔开。本白皮书将不对 C/V 分析进行详述,但有许多关于此主题的文章和书籍可供感兴趣的读者参考。

在基于 SOA 创建“企业管理应用程序”的工厂中,“数据访问”是一个强制功能(因为每个解决方案都将执行数据访问),但“Web 前台”却是一个可选功能(因为一些解决方案将带有 Web 前台,而另一些解决方案将带有 Windows 前台或甚至根本没有前台)。

在工厂中,您可以使用功能模型来描述可能在该产品系列的某一成员中出现的功能,以将通用功能与可变功能分开,并指明可变功能的出现方式。(功能模型由 Czarnecki 和 Eisenecker 进行详细描述。有关详细信息,请参阅本白皮书中的部分。)功能模型也可定义关于可变功能的决策相互影响的方式,例如,声明一个可变功能需要另一个可变功能,或一个功能与另一个功能不兼容。通过配置功能模型来为给定应用程序做出这些决策。配置是一个简单的过程,它涉及到指定哪些由模型描述的可变功能在应用程序中出现以及它们中每个功能的出现方式。图 1 显示的是上文所述工厂的一个简单的功能模型。

.

图 1. 功能模型示例

尽管功能模型通常用于按要求呈现的用户可见功能,但它们也可用于仅对开发人员可见的设计、实现、测试和部署功能。某些功能强大的场景通过链接这些功能来启用,以便在配置用户可见功能的同时也配置开发人员可见功能。例如,将用户可见的“前台”功能链接到开发人员可见的解决方案布局功能可能会使工厂根据用户所选的前台类型生成一个默认的解决方案布局。

功能建模只是用于描述可变性的多种知名机制之一。其他机制还包括窗体、表格、向导、设计器、模板、模式、脚本和代码。可变性机制可单独使用,也可以各种组合使用,目的是指定和实现软件工厂中的可变功能。

成功的关键

成功过渡到软件工厂方法的关键因素是什么?您需要具备以下能力:

找到产品中的通用性和可变性。

在生产力和质量方面度量您的产品开发流程目前的绩效。

定义和改进有效支持产品开发的流程。

提供有助于每个人了解所实现的生产力和质量的透明模型,并使用这个透明模型推动文化转型。

同时规划多个项目。

快速、经济地开发将知识和信息进行封装并使其易于重新使用的可重用资产,尤其是自定义工具。

确定特定领域并将自定义工具和流程专用于这些领域,而不是试图将多用途工具和流程应用于所有领域。

度量质量和生产力

既然我们已经大概了解了关于软件工厂的一些知识,那就让我们更深入探讨一下如何在软件上下文中度量质量和生产力。

事实证明,工厂架构为组织量度提供了一个有用机制。由于每个视点都面向软件开发流程的一个特定方面,因此可以使用各视点来定义生产力和质量的目标度量。使用这些度量,您可以收集软件开发流程特定方面的数据。通过分析这些数据,您接下来就可以确定哪些视点需要改进、如何进行改进以及改进后可获得哪些益处。

要实现此方法,您需要确定一种表示产品规模、所用时间和预算以及产品质量的方式。这些度量可用来量化每个视点的可预见性、生产力以及质量。它们也可用于评估您的工厂生产的最终产品。通过度量每个视点以及工厂总体绩效,您可以确定每个视点对工厂总体绩效的影响有哪些,从而确定要投入多少可重用资产来支持给定视点中的活动。例如,您可以为没有明显影响到总体效率的视点提供简单的指南,为明显影响到总体效率的视点提供高级的基于“域专用语言”(DSL) 的设计器。

此方法类似于大型企业组织优化其业务流程的方式。他们针对特定业务目标定义生产工作产品所需的技能、流程和工具。从这时起,他们度量要完成该流程所需要执行的工作,然后分析哪些方面可予以批准。他们称其为“业务流程监控”,但它基本上还是考评在优化软件工厂时要执行哪些工作。显然,在建立工厂当前绩效的基准线和确定要在软件工厂开发方面进行的正确投资时,度量是一个关键因素。此过程有助于您在可预见性、生产力和质量方面获得最佳投资回报。它还有助于将结果与最初在开始开发工厂前设定的目标进行对比。

使用功能点表示产品规模

在软件开发中,我们可能想要提高的一个方面就是生产力。要量化生产力,您需要一个可用来根据在一段时间内构建的软件产品量来表示生产力的量度。当我们能够预测系统规模并度量开发过程中产品规模增长量时,我们就可以更好地预测完成该项目所需的时间并根据单位产品规模所用的小时数来度量生产力。通过度量实际的增长量和规模,我们能够鉴别实际值与计划值之间的差异,并在差异变得明显时开始对其进行分析和管理。

此时,您可能想知道我们如何才能以足够的准确度来预测产品规模和增长量,以使这种度量和分析发挥作用。如果我们以一次一个项目的方式开发任意的应用程序,这看起来的确不太可能实现。不过,如果我们使用软件工厂,我们就有两个可显著提高可预见性的优势。首先,我们开发的是具有已知特征的特定产品系列的一个成员,而不只是一个任意的应用程序。通过软件工厂,我们可以描述一个产品系列及其突出功能,更重要的是,我们可以一边随着多个项目的进展过程积累经验,一边来逐渐优化该描述,因此,对于使用工厂开发的应用程序,我们所掌握的知识和信息要远多于对任意应用程序所掌握的知识和信息。其次,我们将通过应用工厂提供的规定性指南来开发应用程序。因此,我们有许多开发任务在前后各应用程序中的执行方式都大体相同,使用的是一些相同的模式、模板、库和工具。如果我们将执行某些任务的方式标准化,工厂往往就会从开发流程中剔除不必要的变更,使前后各应用程序的产品规模和增长量更有可能遵循相似的模式。 如果我们使用软件工厂,则度量这些值并确定、分析和管理计划值与实际值间的差异就会极其有用。

目前已经有多种估计方法可帮助您确定系统规模。如果您想要一个有助于表示规模和生产力的量度,您需要一个目标定量。此目标定量可通过使用标准化的方法实现。其中一个方法就是 ISO 24570 标准中定义的“功能规模度量”(Functional Size Measurement)。(ISO/IEC 24570:2004 指定了度量软件功能规模的方法,提供了关于如何确定软件功能规模各组件的指南,详细说明了如何按照上述方法计算功能规模,并提供了上述方法的应用指南)。此 ISO 标准将功能点用作基于功能规范表示软件系统规模的方法。可将这些功能点视为确定系统规模和预估工作及日程表的“总量度”。在开发期间,此量度可用于确定相对于其他类似项目,该项目是需要执行多一些工作还是少一些工作。

借助功能点,您可以根据业务功能定义系统规模。此功能根据您收集的早期需求来确定,并使用规范来进行评分。功能点分析充分利用了构建面向数据库的应用程序的知识和信息,只要您构建的系统在数据库中使用数据操纵,就可应用该方法。功能点是根据对两个数据的了解计算得出的:您的应用程序将含有的表格估计数;数据操纵函数(如数据检索函数和数据更新函数)的数量。由此,您可以计算出表示产品规模的功能点的数量。在表示了估计的产品规模后,您可以了解实现一个功能点要花费多少时间,甚至可以使用已有的历史数据对实现一个功能点要花费的时间进行预测。软件工厂可影响实现一个功能点所用的时间(生产力),每个功能点的缺陷数(质量)以及您的估计数据的可预见性。

再深入探讨一下可预见性,我们已经了解到,工厂是如何允许我们将一个产品系列所有成员的通用功能与仅在某些成员中出现的可变功能或在不同成员中有不同规模或特征的可变功能相分离。因此,我们无需从头收集对给定产品的需求,而是可以假定该产品具有所有系列成员共享的通用功能,并仅将重点集中在详细说明其独特或可变的需求上。

返回工厂上下文中的功能点分析时,我们发现可以将一个始终都存在的固定的最小产品规模作为起点,因为我们的产品系列始终都包含某些固定部分。这个固定的最小产品规模即是该产品系列通用功能的一个度量。我们也可以为许多可以或不可以添加到产品基本配置文件中的可变功能定义可计算规模。从这些信息中,我们可以估计出某一功能配置将要花费的时间和成本。接下来,该信息还可以帮助我们决定要构建哪些功能。换言之,基于功能配置的功能点分析为我们提供了一种预先对成本和功能做出明智权衡的方法。

例如,假设我们应用了功能点分析,并确定我们将要构建的系统的估计规模是 500 个功能点。当我们开始构建此系统时,我们可确定构建它要花费 6,500 个小时。由此我们可以将生产力表示为 13 小时 (h)/功能点 (fp)。

如果我们还在开发、用户验收测试和生产过程中跟踪在产品中发现的缺陷数,则也可以将该数字表示为一个质量量度。假设我们在开发过程中发现 500 个程序错误,在验收测试过程中发现 50 个程序错误,在投入生产后发现 5 个程序错误。我们可以将其表示为,开发过程中是 1 个缺陷/fp,验收测试时是 0.1 个缺陷/fp,生产中是 0.01 个缺陷/fp。

现在,假设其中许多缺陷可追溯到前台应用程序视点。由此我们了解到,在造成所有这些缺陷的原因中,此视点占了很大一部分比重,我们可以集中分析此视点范围内哪些方面可能需要改进。通过这种分析,我们可以确定要改进哪些视点以及如何改进,以减少下次使用工厂时发现的缺陷数。将缺陷数与某量度(如功能点数量)的比值进行量化的好处是,您现在可以为希望通过投资实现的改进方面设定目标。例如,我希望前台应用程序视点的每功能点缺陷数下降 20%。对每个视点逐一执行缺陷和功能点分析为我们改进产品开发流程提供了强大工具,因为它有助于我们确定瓶颈所在之处,从而确定在何处投资以及如何投资才能获得更好的结果。

如果您有更多的开发任务要执行,并且该开发任务涉及到您已收集量度的视点,则刚才所阐述的基本量度可以让您了解有关下一个项目(也许甚至是当前项目)的一些有价值的信息。例如,假设在收集需求并应用功能点分析后,您知道新系统的规模将是 750 fp。您现在就可预测到,实现这些需求将需要约 9,750 个小时的工作,并且将在用户验收测试中发现约 75 个程序错误。

这些预测的准确度在很大程度上取决于您收集的量度级别以及未来的系统开发项目与已收集量度的项目的相似程度。软件工厂中的每个视点都允许在系统开发中有一定量的可变性。可变性的量又依次决定了视点可向工厂用户提供的资产类别,从而决定了前后项目之间在产品该方面的一致性程度。例如,在工厂的第一个版本中,可能只有几个描述系统体系结构和只提供支持开发人员完善实现的指南的视点。使用此工厂的开发人员将不得不手动编写大量代码。不过,在使用此工厂构建多个系统后,您可能会看到,由于各个开发人员对指南的理解都截然不同,这些系统的用户界面部分的构造也往往是多种多样。从这个观察事实可以得出结论,用户界面视点允许大量可变性。如果您的工厂中有多个可变性很高的视点,则您的度量值和预测值准确度要低于在视点中可变性有限时的准确度。

此时,我们可能会问到,给定视点中的可变性程度是否真的必不可少。如果不是,我们将能够通过剔除过多或不必要的可变性来提高度量值和预测值的准确度。例如,让我们再一次探讨用户界面视点,但这次我们提供了一组支持指南的库组件和一个配置用户导航路径的图形工具。通过提供这些资产,我们将对用户界面开发流程中先前松散定义的某些方面进行形式化。这种形式化减少了用户界面视点允许的可变性的量。使用此工厂开发的系统将在用户界面构造中展现出更多的一致性,从而使我们的度量值和预测值更加准确。由于估计数据中的错误量会随着工厂允许的可变性的减少而减少,因此,在工厂通过剔除过多或不必要的可变性而逐渐演化的过程中,可预见性也会随之提高。实际上,生产力和质量往往也会随可预见性提高,因为减少可变性也就减少了构建给定功能所需的时间量以及在其构建过程中引入的缺陷数。此时,有一则警言妙语用在这里很适宜:按照 Occam 的剃刀法则,应尽可能多地减少可变性,但绝不要减少到因过分限制开发人员而使项目耗时更长、成本更高的程度。

当您着手使用功能点时,最初可以使用文档资料中记载的周围组织的历史数据来进行第一次估计。历史数据还是很有帮助的,因为它将组织影响(无论是已被公认的还是未得到公认的)考虑了进去。这一理念也适用于在软件工厂内对历史数据的应用。使用软件工厂开发的各个项目将有许多共同之处。即使没有过去项目的历史数据,您也可以从当前项目收集数据并将其用作预测项目余下部分的基准。您的目标应从使用组织数据或行业平均数据尽快转换为使用工厂数据和项目数据 (McConnell, 2006)。

使用度量改进工厂

通过建立基准或实际校准生产力和质量参数(以小时数/功能点和缺陷数/功能点测得),您可对项目数据进行分析,然后识别那些可能会花费大量时间的活动或产生大量缺陷的视点。校准完毕后,就可以着手更改工厂的组织方式,通过各种途径(如所要求的技能、定义的流程或提供的可重用资产)对其加以更改。确定哪些区域需要改进是至关重要的,以便保证投资到位。但这应该相对容易一些,因为您掌握了用以确定每个视点对可预见性、生产力和质量作出多大贡献的途径。在使用原始数据建立基准后,就可以连续不断地运行以下循环:分析每个视点的性能,使用这些信息确定需要改进的区域,执行改进,然后重复这个过程。

这一有效循环可用于实现各种度量。例如,要提高生产力,可根据小时数/功能点来确定效率最低的视点,然后通过各种方法对其加以改进:提供更多更好的指导或培训;改进用于构建工作产品初始切割的模板;提供用于实现工作产品构建和修改自动化的专业化工具;等等。这一过程的关键部分是估算进行指定改进的成本、估算因改进而可能提高的生产力以及估算结果是否证明投资正确。在实现改进并将其并入工厂后,您可以根据减少的工时数/功能点来度量该改进是否满足预定目标。图 2 阐明了这一过程。

.

图 2. 工厂开发的迭代循环

应用 Visual Studio Team System

既然我们已经学习了如何定义工厂以及如何使用度量和分析对工厂进行迭代优化,现在将考虑如何使我们的产品开发团队能够利用工厂来创建所需的工作产品。这一实现要从支持整个产品生命周期(从产生到废止)的开发环境着手,例如 Visual Studio Team System。使用 Team System 是能够使产品开发团队从先前介绍的方法中受益的关键。

Team System 大致分为两个部分。Visual Studio Team Edition(供架构师、开发人员和测试人员使用的 Team Edition)安装在开发机器上,它是 Visual Studio Development IDE 的一部分,为开发团队中的特定角色提供工具。第二部分是 Team Foundation Server (TFS),它用于托管 Team System 核心生命周期的各个方面,如版本控制、工作项目追踪、团队构建、团队门户以及数据仓库(其中包含使用 TFS 的项目的数据)。

使用 Team System 实现工厂

目前,Team System 并不了解软件工厂。不过,由于 Team System 非常容易配置和扩展,我们可以手动将其设置为支持软件工厂,也就是将工厂架构的各部分映射到各配置元素或扩展点上。

请记住,软件工厂包含用于描述其组织的架构。正如我们已经看到的,工厂架构定义了一组相互关联的视点,每个视点用于描述特定角色用户的相关工作产品、活动和资产。我们可以借助这些信息配置 Team System 进行应用程序开发。

视点可映射到一个或多个迭代中的概念,Team System 称之为区域。与视点关联的角色可映射到一个或多个 Team System 项目角色。实际上,多个视点角色可能会映射到一个 Team System 项目角色。创建项目时,可将视点定义的活动作为工作项目添加到这些区域中,并直接分配给适当的角色。还可以通过定制过程指南将它们记录在案,并创建自定义工作项目类型来追踪它们以及将它们链接到工作产品。有些工作产品可以使用自定义工作项目类型加以描述。可将内容资产(如指南、模式和模板)添加到项目门户文档库中。可执行资产(如工具和类库)可放置在版本控制系统中。为了度量和提高工厂性能,可将量度添加到 Team Foundation 数据仓库中。

配置 Team System 的关键是项目创建向导和过程模板。项目创建向导是在 TFS 中创建项目的工具。它使用用户选择的文件(称为过程模板)来配置项目的服务器。该模板包含许多部分,每一部分都介绍了服务器的一个特定部分的配置方法。例如,使用过程模板可以定义工作项目类型、定制版本控制、定义区域和迭代、定义角色、为每个角色分配适当的权限、设置项目门户以及用以完成定制开发环境和开发过程的许多其他事情。

让我们了解一下如何使用项目创建向导和过程模板以将 Team System 配置为支持软件工厂。

定义工作项目

Team System 使用工作项目来追踪创建指定产品所必须完成的工作。工作项目用于描述必须完成的工作,由它们来确定在特定时间点负责该工作的人员。工作项目可以属于不同类型,以描述不同种类的工作。例如,错误可由 Defect 类型的工作项目来描述,其中包含与修复错误相关的信息,如错误的描述、重新生成步骤、分析或修复错误所需的估算时间,等等。工作项目类型通过更改已载入服务器中的 XML 定义创建或修改,然后在项目创建时进行使用。也可在项目建立后进行修改。

有些类型的工作项目是由 MSF for CMMI Process Improvement 定义的,如 Bug 和 Requirement,它们用于描述工作产品。Task 类型的工作项目用于描述某工作产品从一个阶段到另一个阶段所执行的活动。可将这两种类型有效地用在工厂中,因为它们与用于定义该工厂的概念非常相符。特别是,我们可以为由视点定义的工作产品预订工作项目,为关联的活动预订任务。通过这些工作项目,我们可以收集关于每个活动需花费多少时间的信息,然后就可以知道该活动对工厂生产力有多大影响。

执行映射时遇到的问题之一是工作项目当前未相互嵌套。不能嵌套工作项目会难以描述聚合或复合视点(如上面所述的“数据访问层”视点)的工作产品。您还会发现,在典型的团队项目中,许多工作产品并不是由工作项目进行明确描述的。例如,我们不是创建一个工作项目来描述数据访问库,而是创建一个工作项目来描述数据访问库的构建,然后将工作项目链接到配置管理系统中该库的源文件。另一个问题是,Team System 任务并不像工厂中的活动那样在满足条件之前和之后都执行,因此没有记录将它们移入或移出范围的条件,必须手动制定计划决策。

定义区域和迭代

工作项目可链接到所谓的项目区域和迭代。区域提供了一种方法,使您能够在想要针对数据仓库中的累积数据运行报表时预定感兴趣的解决方案特定部分的工作。Team System 中的区域与软件工厂中的视点概念非常相符,因为这两者均代表感兴趣或关注的区域。

注册在感兴趣的特定区域上完成的工作后,您会查明哪些区域包含的错误最多或消耗的时间最长。将工作项目追踪中的感兴趣区域映射到工厂视点后,就可以使用这些量度来为特定视点提供生产力和质量度量了。

要从工作项目获得正确信息,您必须在开始产品开发时正确定义区域和迭代。通过为即将开发的产品类型定义感兴趣的视点,您能利用工厂简化这一任务。要想正确建立区域,只需为每个视点定义一个区域。然后可能需要将视点名称映射为您的开发团队所熟知的区域名称,这样,团队成员能够轻松地识别出指定工作项目所属的那个区域。

为工厂定义视点时,开始时最好使用一组常常会出现在许多工厂中的通用视点。在 Business-Collaboration Software Factory 的架构中提供了这些通用视点的有效示例(请参阅本白皮书的结尾部分)。其中,已证实在配置 Team System 时特别有用的两个通用视点是 System Engineering 和 Project Engineering。在 System Engineering 区域中,您应该生成一个子树,其中包含用于描述系统突出部分的体系结构视点。这有助于确定系统中的哪些部分对生产力(花费的时间)和质量(缺陷数)的影响最显著。Project Engineering 也是值得关注的区域,因为它能够帮助您以形式化项目中活动的方式来查找异常情况,它还能够帮助您决定是否改进特定点的过程定义。图 3 显示了一个区域和迭代的示例,它反映了一个简单工厂的架构,该简单工厂用于构建包含多个前端的面向服务的管理应用程序。

.

图 3. 用于反映视点的区域定义示例

您为工作项目追踪定义的区域将随同工厂一起发展。工厂成熟时,组成工厂架构的一组视点会发生变化,您要度量的一组视点也会变化。如果您试图合并由工厂定义的所有视点,区域树会变得相当深。不要将树分成许多个不同的级别,这一点非常重要。请记住,区域树越简单越好,这样团队成员才能够轻松地识别出工作项目应该链接到的那些区域。树嵌套得越深,为指定工作项目找到正确区域就越难。如果难度太大,开发人员会仅仅在层次结构的根附近预定工作项目,从而使创建深度嵌套的树失去意义。

定义角色

您在 Team System 中创建的角色应该反映工厂架构中由视点标识的所有角色。这些角色不必与由视点标识的那些角色完全相同,但项目中的每个角色都应该映射到由视点标识的一个或多个角色。因为由视点标识的角色通常要比为项目定义的角色更为精细,所以,一个项目角色通常可实现多个相关的视点角色。

配置产品功能

通过修改向导和过程模板,用户可以启用由 TFS 随附的默认向导和过程模板启用的配置之外的配置。事实上,您可以创建向导自定义页面,用户可利用这些页面对工厂定义的一部分可变功能进行配置。回到前面的示例,即配置为使用不同数据库产品的数据访问构件块,您可能会先询问用户要使用哪个数据库产品,然后在版本控制中放置一个针对该产品预先配置的构件块版本以着手开发项目。虽然软件工厂通常会要求配置贯穿整个开发过程,但定制项目创建向导和过程模板格式确实是一个良好的开端。图 4 显示如何使用自定义向导页面来配置图 3 中显示的功能模型。

项目创建向导是主要的可扩展点,它完全支持查找具有通用性的资产的软件工厂概念。将这些资产拿来,然后单独进行开发。为要重复使用的资产定义所需要的不同可变性,然后使用向导页就针对此特定项目必须怎样设置变量来询问用户。然后向导基于输入进行定制,并根据项目的需求来定制资产。虽然软件工厂中的通用性和可变性概念超出了这些资产的预配置范围之外,但这可以作为定制的起点。配置选定资产后,工厂可能还会提供其他配置工具,以在项目初始设置完毕后更改选定配置。

在工厂中,您将使用先前显示的功能模型来描述您想要使用的可能功能、对一个功能作出的某些决策影响其他功能的方式以及工厂实例的创建方式。正如您在图 1 的示例中所看到的那样,您可以创建一个功能模型来模拟工厂的一组功能,从而实现使用 SOA 来开发管理应用程序。

图 4 显示了在允许用户预配置工厂的自定义向导页中如何反映此模型。

.

图 4. 项目向导自定义页

除了项目创建向导外,至少还有两种方法用以支持团队项目设置方面的配置。您可以定制版本控制存储库来预见即将在解决方案开发过程中采用的主要配置决策。这样,可便于您在采用决策前将解决方案的状态保存在配置管理中以及在以后必须更改决策时将其恢复。这项技术称为回溯。您还可以定义用于捕捉配置决策的工作项目类型,然后在作出决策时将这些类型的实例添加到工作项目追踪数据库中,以捕捉产出及安排随之而来的工作。

定制项目门户

Team System 提供了一个项目门户,开发团队可利用它来共享项目相关信息。此门户也是特定过程模板的过程指南的入口点以及可重用资产(如模板和指南)的入口点。上传到门户的可重用资产由过程模板提供。您还可以更改过程指南网站中显示的内容。使用 InfoPath 文档来执行这一定制。编译 InfoPath 文档以创建一个可并入过程模板的新网站。上传新过程模板后,就可以创建那些使用您所定制的过程指南网站的团队项目了。

向数据仓库添加度量值

Team System 数据仓库可记录有关解决方案开发的所有类型的信息。数据仓库中有一部分存储的是有关工作项目的信息,如前所述,从工厂的角度来看,这部分信息很重要。数据仓库的其他部分则存储的是有关测试、日常构建和其他 Team System 功能的信息。可以通过两种方式来扩展数据仓库以支持度量值。

首先,可以通过修改特定工作项目类型定义来更改仓库中为该工作项目类型保留的字段,修改方式是更改工作项目类型定义中所包含的字段,或者向仓库中的新事实或维度添加字段。当某字段在工作项目类型定义中标记为“可报告”时,该字段就会动态添加到数据仓库中。当然,如果您希望显示有关这些附加字段的报告,则还必须为这些数据创建报告并将其上载到报告服务器,以便其他团队成员可以访问它们。

其次,您可以将自定义工具生成的数据进行合并。如果您的工厂提供了生成数据的自定义工具,并且您希望在数据仓库中使用这些数据,则可以向 TFS 添加一个自定义数据仓库适配器,如图 5 所示。

.

图 5. Team Foundation Server 数据仓库体系结构

单击查看大图像

例如,要根据代码行数来度量每个解决方案的规模,可以构建一个计算文件中代码行数的自定义工具以及一个自定义数据仓库适配器。在您的日常构建中还要多加一步,即对当前解决方案中的所有源代码运行您的自定义工具,然后将结果放到一个文件中。随后,自定义数据仓库适配器会从该文件中提取信息并调用 Team System 所提供的数据仓库对象模型,以将信息添加到数据仓库中。可使用自定义报告查看自定义数据。

使用度量构造 (ISO 15939)

到目前为止,我们已经探讨了如何定义工厂、使用度量和分析优化工厂以及配置 Team System 以支持工厂。在将这些见解综合到一起以通过 Team System 构建和优化软件工厂之前,我们还要了解一件事情:如何收集正确的信息。

我们需要的是待度量对象与支持优化所需信息之间的关系的正式定义。这些定义被称作“度量构造”。度量构造是基本度量、派生度量和指标的组合。基本度量使用指定的度量方法来收集某些软件实体的单个特性信息,其在作用上独立于其他所有度量。派生度量被定义为两个或两个以上基本度量和/或派生度量的函数,可收集多个特性的相关信息。指标是通过将分析模型应用于一个或多个基本和/或派生度量来提供估计值或评估值的度量,用于解决指定的信息需求。指标是度量分析和决策的基础。度量构造描述了信息需求、相关实体和特性、基本和派生度量、指标以及数据收集过程。可以向基本度量、派生度量和指标添加其他的规则、模型和决策条件。图 6 例示了度量构造的结构 (McGarry, 2002)。

.

图 6. 度量构造的结构

单击查看大图像

在 ISO/IEC 15939 中,已根据 ISO 国际度量衡学词汇表对有关软件度量标准和度量方法的关键术语进行了定义。本白皮书中所用的术语源自 ISO 15939 和 PSM(实用软件度量)。

定义度量构造

要定义可添加到我们的 TFS 数据仓库中的度量构造,应采用以下步骤:

定义和分类信息需求

为确保度量我们需要的信息,必须清楚地了解我们的信息需求以及这些需求与我们所度量信息之间的关系。经验表明,软件开发中的大部分信息需求都可以归入到 ISO 15939 定义的七大类别之一:日程表和进度、资源和成本、产品规模和稳定性、产品质量、流程绩效、技术有效性以及客户满意度。产品规模和稳定性类别中的一个信息需求例子可能是“评估软件产品规模以鉴定最初预算估计值”。

这些信息需求可用于度量软件工厂中特定视点的属性。必须将这些信息需求进行优先顺序排列,以确保度量程序能够将重点集中到那些对已定义目标的潜在影响最大的需求。正如先前所述,我们的主要目标通常是确定哪些视点的改进将产生最大投资回报。由于各视点是互相嵌套的,因此我们通常可将度量值逐渐累积到更高级别的视点。例如,如果我们有一个“用户界面”视点,其中包含了“Web 部件开发”和“用户授权”之类的视点,则我们可以将客户满意度度量值从特定的 Web 部件累积到用户界面级别。

定义实体和特性

可度量特性也就是软件实体的可辨识属性。与信息需求(例如“评估软件产品规模以鉴定最初预算估计值”)相关的实体可能是一个开发计划或日程表,以及一组已建立基准线的源文件。其特性可能是每个期段计划完成的功能点、源代码行数和所用编程语言的语言表示表。

定义基本度量和派生度量

基本度量在作用上独立于其他所有度量并收集关于单个特性的信息。指定基本度量可采用的值范围和/或类型有助于检验所收集数据的质量。在本示例中,有两个基本度量:软件产品的估计规模和实际规模。这两个基本度量的数值范围是从零到无穷大。派生度量可收集多个特性的相关信息。图 7 举例说明了这些术语。

.

图 7. 软件规模增长量的基本和派生度量

单击查看大图像

指定指标

指标是度量分析和决策的基础。它们是呈现给用户的度量值。要正确使用指标,其用户必须了解指标所基于的度量与指标所展现趋势之间的关系。因此,度量构造应为每个指标提供以下信息:

用于分析信息的指南。对于本示例,我们所提供的分析指南可能是这样:“不断增长的软件规模增长比率表明达到成本和日程预算的风险越来越高。”

用于根据信息做出决策的指南。对于本示例,我们所提供的决策指南可能是这样:“查明软件规模增长比率变化量何时超出 20%”。

解释指标的图解。对于本示例,我们可能提供类似图 8 的图解并做出如下描述:“指标似乎表明项目生产率比原计划提前了。但经过进一步调查,结果是因为疏漏了直到初始测试时才明确的需求,某一项目的实际规模超出了计划规模。资源分配、日程安排、预算以及测试日程表和计划均受到了这个意外增长量的影响。”

.

图 8. 指标图形表示,软件计划增长量与实际增长量的对比

定义数据收集过程

既然我们知道了如何将基本度量与信息需求相关联,就必须要定义数据收集过程。数据收集过程指定了数据收集频率、负责人、将要收集数据的阶段或活动、确认和验证规则、用于数据收集的工具以及存放所收集数据的存储库。

使用度量构造

要成功使用度量构造,必须解决两个重要问题:影响指标和避免失效的度量。

影响指标

要成功使用指标进行度量分析、做出决策和更改流程,就必须确保其用户知道这些指标代表什么、如何解释指标以及可以变更哪些方面来影响其结果。对于本示例,用户必须了解,要使“功能点实际规模”达到“功能点计划规模”,我们必须在同样多的时间内生产出更多功能点(也就是说,我们必须提高生产力)。用户还必须了解如何提高生产力。

避免失效的度量

决策者还必须知道如何避免失效的度量。度量的目标是通过做出变更(如执行不同的活动、应用不同的资产等等)来改进绩效。重要的是要确保变更合情合理。您不希望人们为了在某些度量中取得预期结果而做出阻碍生产力的变更。在本示例中,要达到“功能点计划规模”的压力可能会很高,以使得人们开始用附加代码行来加长实现。确定并描述风险是实现成功度量的一个关键之处。最好的方法是避免逐一度量。对于任何定量社会指标来说,与其关联的权重越大,就越有可能歪曲和破坏该指标想要改进的流程。

综合利用

最后,综合一下我们所学过的内容并就如何定义和使用度量构造以改进 Team System 支持的软件工厂加以探讨。

向数据仓库添加度量构造

如前文所述,每个度量构造至少都需要定义信息需求、实体和特性、基本度量和派生度量、指标以及数据收集过程。要将这映射到 Team System 数据仓库,我们必须确定如何获得所需信息,或者通过修改工作项目类型定义以添加字段并将其标记为事实或维度,或者通过构建自定义工具以及收集工具所生成数据的自定义数据仓库适配器。我们还必须确定如何显示指标,通常是通过创建 Microsoft SQL Server 2005 Reporting Services 自定义报告来实现。

迭代式改进

将工厂映射到 Team System 之后,就可以开始使用它构建解决方案。它将指导您的团队构建解决方案,并根据您定义和实现的度量构造为您提供信息。从这时起,您就可以开始分析度量值并使用指标来确定改进时机。利用该信息,您可以确定哪些视点可以改进、改进这些视点会得到多大收益,以及要进行多少投资来改进它们。最后,您可以执行已选择的改进,通常是通过添加指导和提供更好的资产来支持工作产品的创建。在利用这些改进构建解决方案时,可以再次使用度量值和指标来确定所实现收益与期望收益的对比情况,并相应调整投资计划。

结论

目前我们构建软件采用的是“一次性”或一次一个项目式开发,这种极其低效的方式需要改变,本白皮书正是在这个愿望的促使下撰写而成。客户明白,我们一直在力争做到项目能按时交付、不超出预算,并且具备所有期望的功能。通过收集从经验中获得的知识和信息并使用软件工厂将其传递给其他项目,就可以全面拯救我们自己和我们的行业。我们了解了如何定义工厂以及如何在生产力和质量方面来度量工厂绩效。

通过量化所构建产品的规模、度量构建产品所耗费的时间以及记录所发现的缺陷数,我们可以描述工厂的绩效。从工厂架构到 Team System 的映射通过使用 Team System 中的自定义和可扩展性功能点完成。可以通过将工厂架构确定的资产放置在版本控制存储库或团队基础门户中来设置 Team System。可以使用该门户来为工厂架构描述的活动提供流程指导。可以使用项目创建向导来安排工厂的初始设置,还可以使用功能建模来创建映射以定义要添加到向导中的窗体。初始项目的很大一部分使用流程模板完成,也可以修改这些模板以支持我们的工厂。

通过定义度量构造并在 Team System 数据仓库中实现它们,我们可以收集在生产力和质量方面描述软件工厂绩效的量度。随着时间的推移,我们可以使用这些量度不断改进工厂,不仅可以提高生产力和质量,还可以通过剔除多余或不必要的可变性来提高可预见性。

利用 Visual Studio Team System 实现软件工厂的最终结果是,项目的成功程度和客户满意度都会有一个质的飞跃。

参考资料

Austin, Robert D. Measuring and Managing Performance in Organizations. New York, NY:Dorset House Publishing Co., Inc., 1996.

Greenfield, Jack, and Keith Short. Software Factories:Assembling Applications with Patterns, Models, Frameworks, and Tools. Indianapolis, IN:Wiley Publishing, Inc., 2004.

McConnell, Steve. Software Estimation:Demystifying the Black Art. Redmond, WA:Microsoft Press, 2006.

McGarry, John, et al. Practical Software Measurement:Objective Information for Decision Makers. Boston, MA:Addison-Wesley Professional, 2002.

关于作者

Marcel de Vries 是荷兰 Info Support 的 IT 架构师,同时也是 Visual Studio Team System 的 MVP。他是 Endeavour 软件工厂的首席架构师,致力于创建面向服务的企业管理应用程序,Info Support 的许多大型企业客户都使用这些应用程序。他还是荷兰当地活动(包括“开发者日”和 Tech-Ed Europe)的著名发言人。 他同时还担任 Info Support 知识中心的兼职培训师。您可以在 http://blogs.infosupport.com/marcelv/ 阅读他的博客。

Jack Greenfield 是 Microsoft Corporation 的企业框架和工具架构师。他曾经是 Rational Software Corporation 的 Practitioner Desktop Group 首席架构师,以及 InLine Software Corporation 的创始人和 CTO。在 NeXT Computer,他开发了企业对象框架(现在是 Apple Computer, Inc. 的 Web 对象的一部分)。作为一名著名的演讲家和作家,他与 Keith Short、Steve Cook 和 Stuart Kent 合著了备受赞誉的畅销书《Software Factories:Assembling Applications with Patterns, Models, Frameworks, and Tools》(软件工厂:通过模式、模型、框架和工具汇编应用程序)。Jack 还为 UML、J2EE 以及相关的 OMG 和 JSP 规范撰写过文章。他还拥有 George Mason University 的物理学学士学位。

原文出处:http://www.microsoft.com/china/msdn/library/langtool/vsts/Aa925157.mspx?mfr=true

转载于:https://www.cnblogs.com/ClarkChan/archive/2006/12/08/586219.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值