From 1f5e3b52cf8aaed3f17c532d68b46f402c5f69ec Mon Sep 17 00:00:00 2001 From: Xiaoxing Ma Date: Thu, 20 Feb 2020 23:45:31 +0800 Subject: [PATCH] =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E4=BF=AE=E6=94=B9=E8=BD=AF?= =?UTF-8?q?=E4=BB=B6=E5=B7=A5=E7=A8=8B=E8=BF=99=E4=B8=80=E7=AB=A0=EF=BC=8C?= =?UTF-8?q?=E7=95=99=E4=B8=8B=E4=B8=A4=E4=B8=AA=E6=89=B9=E6=B3=A8=E5=BE=85?= =?UTF-8?q?=E5=8E=9F=E4=BD=9C=E8=80=85=E7=A1=AE=E8=AE=A4=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ch1-4-SoftwareEngineering.tex | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Ch1-4-SoftwareEngineering.tex b/Ch1-4-SoftwareEngineering.tex index 0f18306..fab2961 100644 --- a/Ch1-4-SoftwareEngineering.tex +++ b/Ch1-4-SoftwareEngineering.tex @@ -10,7 +10,7 @@ 随着信息技术的发展,软件技术的应用范围不断扩大,应用领域不断深入,50年前的软件和现代软件已经不可同日而语,在最初出现软件的时候,没有人能预计到现在人们对软件的期望,也没有人能想象出通过互联网\index{互联网}和物联网\index{物联网},未来人机物融合\index{人机物融合}系统将会在各类场合服务于广大民众。50年前的核心挑战仍然还是软件工程当前的核心挑战,问题的表述几乎没有变化,只是被赋予了不同的内涵。“软件开发没有银弹” 的预言仍是软件工程研究者和实践者不可逾越之“墙”。 \section{软件工程内涵和知识结构} - 什么是软件工程?如何理解软件工程?软件工程(Software Engineering) 是应用计算机科学理论和技术以及工程管理原则和方法,按预算和进度实现满足用户要求的软件产品的工程,或以此为研究对象的学科~\cite{张效祥2005计算机科学技术百科全书}。其主要关注点,是将\textbf{工程化的手段}并采用\textbf{系统化的方法}进行\textbf{软件开发}~\cite{Laplante:2007}。 + 什么是软件工程?如何理解软件工程?软件工程(Software Engineering) 是应用计算机科学理论和技术以及工程管理原则和方法,按预算和进度实现满足用户要求的软件产品的工程,或以此为研究对象的学科~\cite{张效祥2005计算机科学技术百科全书}。其主要强调的是,是用\textbf{工程化}和\textbf{系统化}的方法进行\textbf{软件开发}~\cite{Laplante:2007}。 软件工程是关注软件生产各个方面的工程学科~\cite{IanSommerville:1982},以下广泛流行的说法从不同的角度表述了软件工程的主要关注点,比如: @@ -38,7 +38,7 @@ \setlength{\hangindent}{2.6em} • 软件工程关注大型程序的构造,协作是大型程序设计的主要机制,中心主题是控制复杂度,管理软件的进化~\cite{van2008software}。 - 从问题求解的角度,Dines Bjorner对软件工程有独特的理解。他认为~\cite{Dines2010software},理解软件工程,需要同时回答“how”(如何进行)和“what”(要做什么)。软件工程应该是艺术、规范、工艺、科学、逻辑、和实践的结合,首先需要基于科学的洞察去综合(即构建和构造)软件,其次需要分析(即学习和研究)现有软件技术,以探清和发现可能的科学内容。他特别强调的几个与众不同的关注点包括:第一,软件工程是一门学科,它把数学知识加以判断和优化\xxm{???},成为数学理论的应用方式,目的是(1)理解问题领域;(2)解决现实问题;并(3)为这些通过计算来解决的问题开发计算系统,建立软件解决方案;第二,软件工程应包含三个分支:(1)领域工程\index{领域工程}(理解问题领域);(2)需求工程\index{需求工程}(理解问题及其解决方案的框架);(3)软件设计\index{软件设计}(实现想要的解决方案)。 + 从问题求解的角度,Dines Bjorner对软件工程有独特的理解。他认为~\cite{Dines2010software},理解软件工程,需要同时回答“how”(如何进行)和“what”(要做什么)。软件工程应该是艺术、规范、工艺、科学、逻辑、和实践的结合,首先需要基于科学的洞察去综合(即构建和构造)软件,其次需要分析(即学习和研究)现有软件技术,以探清和发现可能的科学内容。他特别强调的几个与众不同的关注点包括:第一,软件工程是一门学科,它把数学知识加以判断和优化\xxm{数学知识加以判断和优化 -- 何义?请确认。},成为数学理论的应用方式,目的是(1)理解问题领域;(2)解决现实问题;并(3)为这些通过计算来解决的问题开发计算系统,建立软件解决方案;第二,软件工程应包含三个分支:(1)领域工程\index{领域工程}(理解问题领域);(2)需求工程\index{需求工程}(理解问题及其解决方案的框架);(3)软件设计\index{软件设计}(实现想要的解决方案)。 综上所述,软件工程要解决的问题是\textbf{如何高效高质地开发出符合要求的产品}。其中包含三个方面的含义。第一,软件工程的产出是一类产品,其产品形态是\textbf{软件},这决定了软件工程学科的研究对象。第二,软件工程需要高效高质地开发出这类产品,工程化是使产品开发得以高效高质的手段,一般依赖于管理有序的\textbf{生产过程},其中要依据合适的\textbf{方法},以及可操作的\textbf{质量保障手段}。这构成了窄义软件工程学科的研究范畴。第三,软件产品要用于解决现实世界的\textbf{领域相关问题},它的使用要能为相关领域带来\textbf{价值},进一步地,对领域价值的评判超出狭义软件工程的范畴,其范畴扩展到了应用领域中,因此,\textbf{领域工程}进入广义软件工程学科范畴,同时,\textbf{需求工程}成为领域工程和狭义软件工程之间的桥梁。 @@ -46,7 +46,7 @@ 2014年,《IEEE SWEBOK Guide》 V3.0提出一个软件工程学科的知识体系~\cite{Pierre2014SWEBOK},其中包括15个知识领域,即:软件需求\index{软件需求}、软件设计\index{软件设计}、软件构造\index{软件构造}、软件测试\index{软件测试}、软件维护\index{软件维护}、软件配置管理\index{软件配置管理}、软件工程管理\index{软件工程管理}、软件工程过程\index{软件工程过程}、软件工程模型和方法、软件质量\index{软件质量}、软件工程职业实践、软件工程经济学\index{软件工程经济学}、计算基础、数学基础和工程基础。这个知识分类体系,除了基础性知识领域外,其它的大部分知识领域可以归属为上述软件系统设计和实现的内容。 - 值得一提的是,相比于传统的工程学科,软件工程最大的不同在于它的跨行业性,领域工程和需求工程就是解决软件的跨行业性问题\xxm{建筑不也是么?},包括:如何理解所面对的问题领域(领域工程),和如何理解需要用软件技术来解决的领域问题(需求工程)。在目前即将进入的人机物融合时代,软件工程的跨行业性显得尤为突出,这是软件能够渗透进各行各业并通过行业应用体现其价值性的关键。这两部分内容将在第4节中描述。 + 值得一提的是,相比于传统的工程学科,软件工程最大的不同在于它的跨行业性,领域工程和需求工程就是解决软件的跨行业性问题,包括:如何理解所面对的问题领域(领域工程),和如何理解需要用软件技术来解决的领域问题(需求工程)。在目前即将进入的人机物融合时代,软件工程的跨行业性显得尤为突出,这是软件能够渗透进各行各业并通过行业应用体现其价值性的关键。这两部分内容将在第4节中描述。 \begin{figure}[ht] \centering @@ -67,7 +67,7 @@ 随着软件开发经验的不断积累,人们越来越多地研究软件工程方法,以指导软件设计和实现,目的是使软件开发具有系统性,并成为系统化可重复的过程,从而提高软件开发的成功率。50年来,随着软件解决的现实问题不断深化,软件工程方法不断地出现并得以发展,比如从系统的功能设计和实现角度出发的结构化方法,从面向现实世界问题中实体关系角度出发的面向对象方法,以及从面向现实世界问题求解角度出发的非功能性分析和设计方法等,软件工程方法的蕴含面不断向现实世界发展。 - 如同本书第一章中阐述,软件发展的核心是管理复杂性,软件工程的目标则是控制复杂性,其基本原理是分而治之。这在系统实现层表现为“模块化封装”,在系统设计层表现为“结构化抽象”,在问题分析层表现为“关注点分离”。这在早期的一些代表性工作中就有所体现,比如,1970年代末兴起的模块互联语言\index{模块互联语言}(Module Interconnection Language,简称MIL)就是一种结构化系统设计语言~\cite{prieto1986module},它提倡软件系统由相互联结的模块组成,提供形式化手段刻画模块间的各种联接关系,形成系统规格说明,以支持系统完整性和模块间兼容性等的验证。还有各种体系结构描述语言\index{体系结构描述语言}(Architecture Description Language,简称ADL)就是在接近系统设计者直观认识的抽象层次上描述软件系统的结构,是软件系统高层结构的概念模型~\cite{Taylor2009SoftwareArchitecture}。 + 如同本书第一章中阐述,软件发展的核心是管理复杂性,软件工程的目标则是控制复杂性。这在系统实现层表现为“模块化封装”,在系统设计层表现为“结构化抽象”,在问题分析层表现为“关注点分离”。这在早期的一些代表性工作中就有所体现,比如,1970年代末兴起的模块互联语言\index{模块互联语言}(Module Interconnection Language,简称MIL)就是一种结构化系统设计语言~\cite{prieto1986module},它提倡软件系统由相互联结的模块组成,提供形式化手段刻画模块间的各种联接关系,形成系统规格说明,以支持系统完整性和模块间兼容性等的验证。还有各种体系结构描述语言\index{体系结构描述语言}(Architecture Description Language,简称ADL)就是在接近系统设计者直观认识的抽象层次上描述软件系统的结构,是软件系统高层结构的概念模型~\cite{Taylor2009SoftwareArchitecture}。 软件开发的效率和质量一直是软件工程追求的目标,基于构件的方法尝试采用大规模复用\index{复用}的手段,提高软件的开发效率,以及提升所开发的软件的质量。面向服务的方法则将其它软件提供的服务作为可复用的构件,软件系统通过复用并无缝集成来自不同提供方的服务来获得。除此之外,还有其它软件开发和软件工程模式,比如开源软件\index{开源软件}开发以及敏捷开发\index{敏捷开发}等,它们都从不同的角度来应对软件开发问题,解决软件危机,尝试找到软件开发的“银弹”。 @@ -106,7 +106,7 @@ 构件技术的发展还催生了商用成品构件(Commercial Off-The-Shelf,简称COTS)\index{商用成品构件(COTS)}的出现,例如在信息系统中有着广泛应用的报表构件、文档处理构件等。商用成品构件一般都符合特定的构件标准并具有良好的可组装性,由独立的构件开发厂商提供,应用开发厂商通过购买获得构件使用权,并通过黑盒的方法进行组装和复用。 \subsubsection{面向服务的软件开发方法} - 随着基于Internet的应用的延伸,面向服务的计算(Service-Oriented Computing,SOC)应运而生,其目的是有效解决在分布、动态和异构环境下,数据、应用和系统集成的问题\xxm{这个corba就是这样了,服务计算更进一步}。面向服务的软件开发方法~\cite{Papazoglou2007SOC}通过组合可复用的服务实现软件系统的开发,主要关注如何按需、动态地集成现有的服务,从而快速开发出满足新需求的软件系统。服务提供者和服务使用者之间的交互关系具有动态特性,服务公开性(Exposure)和反射性(Reflection)替代了传统的固定式系统集成,开发软件系统时是根据系统的需求进行服务装配与组合。此外,服务的松耦合改变了传统以APIs调用进行组件组装的紧耦合方式,系统架构师可以通过动态描述组合服务集合来创建软件系统。 + 随着基于Internet的应用的延伸,面向服务的计算(Service-Oriented Computing,SOC)应运而生,其目的是有效解决在开放、分布、动态和异构环境下,数据、应用和系统集成的问题。面向服务的软件开发方法~\cite{Papazoglou2007SOC}通过组合可复用的服务实现软件系统的开发,主要关注如何按需、动态地集成现有的服务,从而快速开发出满足新需求的软件系统。服务提供者和服务使用者之间的交互关系具有动态特性,服务公开性(Exposure)和反射性(Reflection)替代了传统的固定式系统集成,开发软件系统时是根据系统的需求进行服务装配与组合。此外,服务的松耦合改变了传统以APIs调用进行组件组装的紧耦合方式,系统架构师可以通过动态描述组合服务集合来创建软件系统。 面向服务的开发方法包括以下内容:(1) 面向服务的分析和设计:以服务为中心,根据业务需求识别服务、描述服务,并设计服务的实现;(2) 面向服务的开发过程:结合现有开发过程,规划以服务为中心的开发过程中的角色、职责、活动和工件;(3) 面向服务架构的成熟度分析和迁移路线:以服务为中心,分析现有或目标系统的成熟度,并设计从现有成熟度迁移到目标成熟度的路线;以及(4)面向服务架构的监管:设计组织和流程,确保面向服务架构的设计原则在IT生命周期中得以贯彻,管理服务生命周期中各种迁移的合理性等。 @@ -153,7 +153,7 @@ 软件是一种人工制品,需要有相应的质量保障(Software Quality Assurance, SQA)机制,包括监控软件工程过程以确保质量。软件质量保障涵盖整个软件开发过程,包括需求定义、软件设计、编码、源代码控制、代码审查、软件配置管理、测试、发布管理和产品集成等。 \subsubsection{软件质量体系} - 软件质量是反映软件系统或产品满足明确或隐含需求能力的特性的总和。有四个方面的含义: 其一,能满足给定需要的特性的全体;其二,具有所期望的各种属性的组合的程度;其三,用户觉得能满足其综合期望的程度;其四,软件的组合特性\xxm{本段翻译腔明显,不易读,又没参考文献},它确定软件在使用中将满足顾客预期要求的程度。软件质量常常用下列特性来评价: + 软件质量是反映软件系统或产品满足明确或隐含需求能力的特性的总和。有四个方面的含义: 其一,能满足给定需要的特性的全体;其二,具有所期望的各种属性的组合的程度;其三,用户觉得能满足其综合期望的程度;其四,软件的组合特性\xxm{组合特性--何义?另外,本段似乎是翻译而来,不易读,又没参考文献,请确认。},它确定软件在使用中将满足顾客预期要求的程度。软件质量常常用下列特性来评价: \begin{itemize} \item 功能性:当软件在指定条件下使用时,软件产品提供满足明确和隐含需求的功能的能力。 @@ -168,7 +168,7 @@ \item 易移植性:软件产品从一种环境迁移到另外一种环境的能力。 \end{itemize} - 软件质量度量是用于确定软件系统或产品头屑\xxm{头屑??}特性的定量尺度,Boehm等人于1976年提出了定量评价软件质量的概念,提出了60个质量度量公式,首次提出了软件质量度量的层次模型。1978年Walters和McCall提出了从软件质量要素、准则到度量的三层式软件质量度量模型,将质量要素降到11个。 + 软件质量度量是用于确定软件系统或产品特性的定量尺度,Boehm等人于1976年提出了定量评价软件质量的概念,提出了60个质量度量公式,首次提出了软件质量度量的层次模型。1978年Walters和McCall提出了从软件质量要素、准则到度量的三层式软件质量度量模型,将质量要素降到11个。 \subsubsection{软件质量标准} 国际标准化组织于1985年建议的质量度量模型分为三层:高层——软件质量需求评价准则;中层——软件质量设计评价准则;低层——软件质量度量评价准则。在1991年,国际标准化组织(ISO)和国际电工委员会(IEC)又共同提出了标准,给出了6个特性和21个子特性,于2001年再次修订标准,建立了软件产品质量的两分模型:(1)内部质量(软件产品在特定条件下使用时,软件产品的一组静态属性满足明确和隐含需要的能力)和外部质量(系统在特定条件下使用时,软件产品使得系统的行为能满足明确和隐含需要的能力);(2)使用质量(在特定的使用场景中,软件产品使得特定用户在达到有效性、生产率、安全性和满意度等方面的特定目标的能力)。 @@ -176,11 +176,11 @@ 还有一系列标准用于监控和评估软件生产过程过程,以支持软件质量的提升,如,ISO/IEC 15504\footnote{https://www.iso.org/standard/38932.html},其第一个版本专注于软件开发过程,后来扩展到涵盖软件业务中的所有相关流程,例如项目管理,配置管理,质量保障等,是成熟度模型的参考模型,评估者可以根据模型在评估期间收集证据,全面确定所开发产品(软件,系统和IT服务)的能力。其更新版本是ISO/IEC 33000\footnote{https://www.iso.org/standard/54175.html}。其它质量标准还包括ISO/IEC 25000\footnote{https://www.iso.org/standard/64764.html}、ISO/IEC/IEEE 29119\footnote{https://www.iso.org/standard/45142.html}等。 \subsubsection{形式化规约和验证} - 除了采用工程方法来组织、管理软件的开发过程,并根据标准检验过程的正确性外。还有一类工作就是深入探讨程序和程序开发过程的规律,建立严密的理论,以其用来指导软件开发实践,这类工作推动了形式化方法的深入研究,其目标是以严格的数学推演为基础,通过对系统的形式规约、验证和逐步精化来构造并实现软件,从而提高软件设计的可靠性和鲁棒性。其中,形式规约是使用形式语言构建所开发的软件系统的规约,对应软件生命周期不同阶段的制品,刻画系统不同抽象层次的模型和性质。形式化开发就是构造并证明形式规约\xxm{没有模型?}之间的等价转换和精化关系,以系统的形式模型为指导,通过逐步精化,最后开发出满足需要的系统,也称为构造的正确性(Correct by Construction)\xxm{翻译不妥吧}。 + 除了采用工程方法来组织、管理软件的开发过程,并根据标准检验过程的正确性外。还有一类工作就是深入探讨程序和程序开发过程的规律,建立严密的理论,以其用来指导软件开发实践,这类工作推动了形式化方法的深入研究,其目标是以严格的数学推演为基础,通过对系统的形式规约、验证和逐步精化来构造并实现软件,从而提高软件设计的可靠性和鲁棒性。其中,形式规约是使用形式语言构建所开发的软件系统的规约,对应软件生命周期不同阶段的制品,刻画系统不同抽象层次的模型和性质。形式化开发就是构造并证明形式规约和形式模型之间的等价转换和精化关系,以系统的形式模型为指导,通过逐步精化,最后开发出满足需要的系统,也称为保证正确性的构造(Correctness by Construction)。 \subsubsection{软件分析和软件测试} 软件分析和软件测试是软件开发实践中常用的质量保障手段,被广泛用于发现软件需求、设计、实现代码等制品中的缺陷或验证相关性质。 - 软件分析是指对软件制品进行人工或者自动分析,以验证、确认或发现软件性质(或者规约、约束)的过程或活动~\cite{梅宏2009软件分析技术进展}。软件分析的对象覆盖了文档、代码(源代码或二进制代码)、运行时系统\xxm{运行中的系统?}、开发历史等不同形态,相应的分析技术也包括静态分析、动态分析和开发历史分析等。其中,静态分析在不运行程序的情况下,对文档和代码进行分析,抽取各种性质及抽象表示并对各种问题进行检查;动态分析通过程序插装等手段获取程序的运行时信息,在此基础上对程序的行为进行分析;开发历史分析对软件版本库等开发库中所记录的开发历史进行分析,获得与软件演化历史相关的各种信息。软件分析可以直接发现各种软件制品中的缺陷和问题,例如不一致的需求描述、被违反的设计原则、代码坏味道、潜在漏洞和缺陷等。其中,针对代码的静态分析是主要的软件分析手段,涉及语法分析、类型分析、数据流/控制流分析等基本分析技术,符号执行、切片分析等辅助分析技术,以及克隆分析、规范检查、漏洞扫描等针对特定目的的分析技术。 + 软件分析是指对软件制品进行人工或者自动分析,以验证、确认或发现软件性质(或者规约、约束)的过程或活动~\cite{梅宏2009软件分析技术进展}。软件分析的对象覆盖了文档、代码(源代码或二进制代码)、运行中的系统、开发历史等不同形态,相应的分析技术也包括静态分析、动态分析和开发历史分析等。其中,静态分析在不运行程序的情况下,对文档和代码进行分析,抽取各种性质及抽象表示并对各种问题进行检查;动态分析通过程序插装等手段获取程序的运行时信息,在此基础上对程序的行为进行分析;开发历史分析对软件版本库等开发库中所记录的开发历史进行分析,获得与软件演化历史相关的各种信息。软件分析可以直接发现各种软件制品中的缺陷和问题,例如不一致的需求描述、被违反的设计原则、代码坏味道、潜在漏洞和缺陷等。其中,针对代码的静态分析是主要的软件分析手段,涉及语法分析、类型分析、数据流/控制流分析等基本分析技术,符号执行、切片分析等辅助分析技术,以及克隆分析、规范检查、漏洞扫描等针对特定目的的分析技术。 软件测试通过人工或自动的方式运行被测试的软件,检验其运行结果或行为是否与预期相符,其目的是发现软件中潜在的错误和问题。测试应当经过设计,并在测试用例的驱动下进行。测试用例一般包括输入、环境配置、测试步骤和期望输出。软件测试可以在不同层次上进行,包括单元测试\index{单元测试}、集成测试\index{集成测试}、系统测试\index{系统测试}和验收测试\index{验收测试}。此外,在软件进行修改后为确认修改未引入新的错误还需要重新运行相关的测试用例,即进行回归测试\index{回归测试}。软件测试的基本过程包括测试计划、测试用例设计、测试执行、测试结果分析等步骤。其中,测试用例设计是关键,一方面要确保对软件运行过程中的各种可能性有较高的覆盖度,另一方面要限制测试用例数量以节省测试时间和成本。相应的测试用例设计方法主要包括白盒测试\index{白盒测试}和黑盒测试\index{黑盒测试}两类,同时与各种测试用例选取和排序等辅助技术相结合。为了缩短测试时间、节省测试成本,自动化测试技术受到了很大关注,包括自动化的测试用例生成、执行和结果分析。 \subsection{软件工程工具} @@ -273,5 +273,5 @@ \section{结束语} 综观软件工程的起源和发展,可以发现,软件成为独立存在的人工制品,因此需要一种系统化的方法以及相应的技术,第一使得这种人工制品的功能能满足应用需求,第二使得其开发和生产能高效地完成,第三能提供手段以保证其质量。因此软件工程的发展总是围绕需求、软件方法学和软件开发技术、以及软件质量体系和保障等几个方面展开,这形成了软件工程学科的内涵。 - 但是,软件又和其它人工制品不同,它在需求和表现形式上具有极大变化性,它承载在看上去非常容易修改的代码上,随着软件和物理设备以及人的越来越深度的融合,通过软件作为核心支撑来解决的问题也越来越复杂。这也使得软件工程方法和技术不断面临新的挑战,面对的问题(需求)越来越复杂、软件操作的交互对象越来越多样,人们寄予越来越高的可靠性等等,这些是软件工程方法和技术发展的原动力。 + 但是,软件又和其它人工制品不同,它在需求和表现形式上具有极大变化性,它承载在看上去非常容易修改的代码上,随着软件和物理设备以及人的越来越深度的融合,通过软件作为核心支撑来解决的问题也越来越复杂。这也使得软件工程方法和技术不断面临新的挑战,面对的问题(需求)越来越复杂、软件操作的交互对象越来越多样,人们寄予越来越高的可靠性等等,这些是软件工程方法和技术发展的不竭动力。