软件制造工程
第三章 编程工程
3.1.1 编程工程的定义
? 编程工程 就是用程序设计语言把程序设
计的结果和过程翻译为在计算机相应环
境下可运行的软件产品,把系统工程师
按照用户需求设计出来的系统构架变为
真正可运行的软件系统的工程。
3.1.1 编程工程的定义
? 编程工程的作业内容 详细地划分为制定
工作标准,制定编码基准,理解设计书,
程序编码,自查,送上级系统工程师审
查,修改以及进行单元测试等若干步骤,
3.1.1 编程工程的定义
? 编程工程的作业流程
见 P12 图 2.3
3.1.2 易读易懂的程序
? 结构化编程以前,以个人为中心的编程作业
? 程序的规模逐渐扩大,产生了组织行为的软件
开发,而且产生了对过去开发的程序进行修改
后再利用的需求
? Goto语句的使用
? 能够把猛一看很大的很复杂的程序用单纯的方
法分解,分解后的一块一块的程序也都很单纯,
这就是, 易读易懂的程序, 。
3.2 结构化编程
? 结构化开发 --结构化分析、结构化设计和
结构化编程三个阶段
3.2.1 结构化开发过程
结构化编程
结构化设计
结构化分析
需求分析 /
验收测试计划
外部设计 /
系统测试计划
内部设计 /
组合测试计划
程序制造
(编码 &单元测试 )
验收测试
组合测试
系统测试
3.2.1 结构化开发过程
1、结构化分析
? 结构化分析方法的核心是沿数据流程图自顶向
下、逐步求精,是最经典的面向数据流的需求
分析方法。结构化分析方法使用系统流程图、
数据流程图、数据字典,ER图、处理说明等工
具来描述系统的功能需求、数据需求、运行需
求和系统扩充需求。该方法广泛应用于银行,
证券,商务处理,生产管理等大中型信息管理
系统的需求分析过程。
3.2.1 结构化开发过程
? 在软件系统开发的初期阶段,首先要对
用户的现行业务运行系统进行调查和现
状分析,把握用户对新的开发系统的要
求和希望,从用户提供的基本信息中,
整理出开发系统目的和可能实现的功能
范围,设计出新系统的数据流程图
( DFD,Data Flow Diagram),显示屏
幕关连图和功能概要说明书。
3.2.1 结构化开发过程
2、结构化设计
? 结构化设计方法通常也叫做面向数据流的设计、
面向行为的设计。结构化设计方法是以需求分
析阶段获得的新系统的数据流程图 (DFD)和显
示屏幕关连图为基础,通过一系列映射,自顶
向下,逐步细化,把它们变换为具体的程序概
要结构图和屏幕设计式样,把一个个复杂的问
题分解细化为由多个功能模块组成的具有层次
结构的软件系统。
3.2.1 结构化开发过程
3、结构化程序制造
? 结构化程序制造由结构化程序设计和结构化程
序编码组成,它以外部设计和内部设计过程中
获得的软件结构图及其相关设计资料为基础,
采用自顶向下,逐步细化的方法,把一个个模
块的功能逐步分解,细化为一系列具体的步骤,
作出结构化程序设计说明书,程序员再按照程
序设计说明书和系统设计的相关资料,把一步
步的处理说明翻译成一系列用某种程序设计语
言编写的程序代码。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 结构化分析、设计的成果文档
系统功能概要说明书 程序名称一览表
业务处理概要图( ER图) 公共子程序设计说明书
显示屏幕关连 图程序功能结构图
屏幕设计式样书 程序设计说明书
数据库设计说明书 程序处理追加功能说明书
代码设计说明书 模块功能的定义说明书
输入/输出文件设计说明书 输入数据检查说明书
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 在进行程序编码工作的初期,程序员首
先要获取系统功能概要说明书、业务处
理概要图( DFD图或者 ER图)、显示屏
幕关连图和程序名称一览表,理解开发
系统的目的、整体要素和各个子系统的
处理要求。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 程序编码的主要依据是程序设计说明书,在编
写程序代码之前,程序员首先要确认自己所要
编制的程序名称,获取该程序的程序设计说明
书,理解该程序的程序功能概要和各个模块的
详细处理说明,确定该程序所要使用的屏幕和
报表的名称,数据库表和输入输出文件的名称,
以及调用公共子程序的名称,找出所有相关的
设计资料,充分理解程序设计说明书的内容,
若有疑问或不明白的地方,要提出问题,与系
统设计人员进行交流确认。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 在正确理解程序设计说明书的基础上,
构思出结构化程序的框架,必要时作出
程序处理流程图。使用 C语言或者其它语
言编写程序代码时,还要获取相关文件
和 DB的格式定义代码( *.h)或 COPY句,
确认各个数据项目的变量名称。需要调
用公共子程序时,要获得公共子程序的
代码或者可执行文件,做好输入输出参
数的设置和返回值的判断处理。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 在编写程序代码之前,还需要获得编码
测试基准、共通处理说明书和代码设计
说明书、获取相应的例子程序,在正确
理解编码测试基准的基础上,进行程序
编码和编码完成后的单元测试,一定不
要在程序编码测试完成以后,再回过头
来对照编程基准和共通处理说明书,检
查修改与基准不一致的地方,那样既增
加了作业时间又不能保证程序质量。
3.2.3 结构化编码
? 程序代码的质量与软件系统外部设计和
内部设计的质量直接相关,同时,程序
设计语言的特性和程序员的编码水平,
程序代码的可读性,可维护性,可靠性,
可测试性都是直接影响程序质量的因素。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 在进行组合测试之前,需要获取系统功
能概要说明书、数据流程图、编码测试
基准和共通处理说明书,把握各个子系
统的处理流程和各个程序单元之间的接
口,确保实现整个系统的设计功能
3.2.3 结构化编码
? 结构化编码采用自顶向下,逐步细化的
方法,先全局,后局部,先整体,后细
节,先抽象,后具体,逐步求精,编制
出来的程序具有清晰的逻辑层次结构,
容易阅读、理解、修改和维护,可以提
高软件质量,提高软件开发的成功率和
生产性。结构化编码过程中,要遵循以
下几个主要的原则:
3.2.3 结构化编码
⑴ 尽可能使用语言提供的基本控制结构,顺序结构、选
择结构和重复结构。
⑵ 选用的控制结构只准许有一个入口和一个出口。
⑶ 利用程序内部函数,把程序组织成容易识别的内部函
数模块,每个模块只有一个入口或一个出口,一般不
超过 200行。
⑷ 复杂结构应该用基本控制结构组合或嵌套来实现。
⑸ 尽可能减少 GOTO语句的使用,一般限制用到以下两
种情况:
? 把控制转移到出错处理。
? 把控制转移到函数模块结束
3.2.3 结构化编码
? 大量采用 GOTO语句实现控制路径,会使
程序路径变得复杂而且混乱,但有时完
全不用 GOTO语句,可能会增加程序实现
的复杂度。例如,在查找结束时、文件
访问结束时或出现错误情况要从循环中
转出时,使用 GOTO语句会使程序更加清
晰易懂。所以,应该加以限制地使用
GOTO语句。
3.2.3 结构化编码
? 例如,使用 C语言编写下面的一个小程序,
目的是打印出 A,B,C三个数据中的最小
数,如图 3.2给出了程序流程图。
? 程序段 1、程序段 2 比较
3.2.3 结构化编码
? 结构化程序编码就是按照结构化程序设
计说明书,从程序的控制结构入手,自
顶向下,逐步细化,把一个个模块的功
能逐步分解,细化为一系列具体的步骤。
3.2.3 结构化编码
? 在结构化程序的实现方法中,有两种常
用的基本方法,第一是 BREAK处理(见
图 3.3),第二是 MATCHING处理(见图
3.5)
3.2.3 结构化编码
BREAK方法的处理概要如下,处理流程见图 3.4:
① 按关键字项目值的升序读入输入文件的记录,
把关键字项目的值存入工作变量中。
② 关键字项目的值相同时,进行统计处理(或者
其他处理)。
③ 关键字项目的值发生了变化( BREAK)的时候,
把变化前( BREAK BEFOR)的关键字项目值和
统计结果输出到文件中(或者其他处理),用
变化后( BREAK AFTER)的关键字项目值替换
变化前的关键字项目值。
3.2.3 结构化编码
④ 读入输入文件的下一条记录,把关键字
项目的值存入变化后的工作变量中。
⑤ 继续进行上述②至④的处理,直至文件
读入结束。
3.2.3 结构化编码
? 前提条件是:
在进行 BREAK处理之前,输入文件必须
是已经按照关键字项目值进行排序(升
序或者降序)处理好的。
3.2.3 结构化编码
MATCHING方法处理概要说明如下,处理流程如
图 3.6所示。
① 按关键字项目值的升序读入基础文件的记录,
把关键字项目的值存入基础 KEY工作变量中。
② 按关键字项目值的升序读入事务文件的记录,
把关键字项目的值存入事务 KEY工作变量中。
③ 基础 KEY的值与事务 KEY值相等时,把事务文
件的数据编辑输出到文件中。读入事务文件的
下一条记录,把关键字值存入事务 KEY。
3.2.3 结构化编码
④ 基础 KEY的值大于事务 KEY值的时候,把事务 KEY的值
写到错误信息文件中。读入事务文件的下一条记录,
把关键字值存入事务 KEY。
⑤ 基础 KEY的值小于事务 KEY值的时候,读入基础文件的
下一条记录,把关键字值存入基础 KEY。
⑥ 继续进行上述③至④的处理,直至文件读入结束。
1:1的匹配处理的情况下,上述处理③读入事务文件的同
时,还要读入基础文件
3.2.3 结构化编码
? 前提条件是:
在进行 MATCHING处理之前,输入文件
必须是已经按照关键字项目的值进行排
序(升序或者降序)处理好的。
3.3.1 什么是面向对象
? 面向对象 (object-oriented或 object-
orientation)不仅是一些具体的软件开发
技术与策略,而且是一整套关于如何看
待软件系统与现实世界的关系,以什么
观点来研究问题并进行求解,以及如何
进行系统构造的软件方法学。
3.3.1 什么是面向对象
? 概括地说,面向对象方法的基本思想是,从现实世界
中客观存在的事物(即对象)出发来构造软件系统,
并在系统构造中尽可能运用人类的自然思维方式。
? 开发一个软件是为了解决某些问题,这些问题所涉及
的业务范围称作该软件的问题域。面向对象方法强调
直接以问题域(现实世界)中的事物为中心来思考问
题、认识问题,并根据这些事物的本质特征,把它们
抽象地表示为系统中的对象,作为系统的基本构成单
位(而不是用一些与现实世界中的事物相差较远,并
且没有对应关系的其它概念来构造系统)。这可以使
系统直接地映射问题域,保持问题域中事物及其相互
关系的本来面貌。
3.3.1 什么是面向对象
? 自 80年代末期到 90年代,面向对象的方
法与技术向着软件生命周期的前期阶段
发展,即:人们对面向对象方法的研究
与运用,不再局限于编程阶段,而是从
系统分析和系统设计阶段就开始采用面
向对象方法。这标志着面向对象方法已
经发展成一种完整的方法论和系统化的
技术体系
3.3.1 什么是面向对象
? 面向对象的方法与技术发展到软件生命周期的
前期阶段有着更为深刻的意义。因为面向对象
方法的本质,就是主张从客观世界固有的事物
出发来构造系统,提倡用人类在现实生活中常
用的思维方法来认识、理解和描述客观事物,
强调最终建立的系统能够映射问题域,即:系
统中的对象以及对象之间的关系能够如实地反
映问题域中固有事物及其关系。这恰恰是从分
析和设计阶段入手才能根本解决的问题。
3.3.2 面向对象的软件工程方法
? 面向对象的软件工程方法是面向对象方
法在软件工程领域的全面运用。它包括
面向对象的分析、面向对象的设计、面
向对象的编程、面向对象的测试和面向
对象的软件维护 (OOSM)等主要内容。
3.3.2 面向对象的软件工程方法
? 软件开发是对问题求解的过程。按照软
件工程学对软件生命周期的划分,软件
开发过程包括分析、设计、编程、测试
和维护等主要阶段。从认识论的角度看,
整个软件开发过程又可归结为两项主要
活动,即:人们对所要解决的问题及其
相关事物的认识和基于这种认识所进行
地描述。
3.3.2 面向对象的软件工程方法
? 粗略地划分认识与描述,可以把分析与设计看
作对问题及其解决方案的认识,把编程看作对
解决方案的描述。细致地划分,则分析和设计
阶段本身也包括描述,即按一定的软件开发模
型中分析及设计阶段的表示方法,产生分析文
档和设计文档;编程阶段也包括一定的认识和
理解活动,特别是在传统的软件开发方法中,
分析文档和设计文档不能很好地映射问题域,
程序员在书写程序之前,往往需要在分析、设
计文档的帮助下,对程序所要描述的事物进行
再认识。
3.3.2 面向对象的软件工程方法
? 对问题域的正确认识是软件开发工作的
首要任务。没有对问题域的正确认识,
就不可能产生一个正确的系统。描述只
是把开发人员对问题域的认识表达出来,
最终产生一个机器能够理解和执行的系
统实现。
3.3.2 面向对象的软件工程方法
? 既然软件开发是对问题域的认识和描述,按软
件工程学的观点,从认识事物方面看,它在分
析阶段提供了一些对问题域的分析认识方法。
从描述事物方面看,它在分析和设计阶段提供
了一些从问题域逐步过渡到编程语言的描述手
段。但是在结构化的软件工程方法中,这些过
渡手续并不连续。就是说,并没有完全填平语
言之间的鸿沟(如下图)。而在面向对象的开
发中,它们都是紧密衔接的,填平了语言之间
的鸿沟(如下图)。
传统的软件工程方法与面向对象
的软件工程方法
问题域
需求分析
总体设计
详细设计
编程
测试
计算机
自然语言
分析与设计的鸿沟
编程语言
问题域
OOA
(面向对象分析 )
OOD
(面向对象设计 )
OOP
(面向对象编程 )
OOT
(面向对象测试 )
计算机
自然语言
面向对象的编程语
言
3.3.3 面向对象的编程( OOP)
? 面向对象的编程又称作面向对象的实现( OOI)。它
是面向对象方法从诞生、发展到走向成熟的第一片领
地,也是使面向对象的软件开发最终实现的重要阶段。
在 OOA和 OOD理论出现之前,程序员要写一个好的面
向对象的程序,首先要学会运用 OO方法来认识问题域,
所以 OOP被看作一门比较高深的技术。现在,在
OOA→ OOD→ OOP这一软件工程的过程系列中,OOP
的分工比较简单了:认识问题域与设计系统成分的工
作已经在 OOA与 OOD阶段完成,OOP工作就是用同一
种面向对象的编程语言把 OOD模型中的每个部分书写
出来。
3.3.3 面向对象的编程( OOP)
? 我们使用的编程语言直接影响我们观察(建模)
现实的方式。 20世纪 70年代当我们使用 C、
Pascal和 PL/1等编程语言时,我们使用命令式
范围(即结构化方法)对现实建模。 20世纪 80
年代当我们使用关系数据库,SQL和 4GL时,
我们使用数据建模范型对现实建模 — 实体 — 关
系图。今天我们使用 C++,JAVA,Smalltalk和
Objective C编程时,我们使用面向对象的模型
对现实建模。
3.3.3 面向对象的编程( OOP)
? 面向对象编程的基本概念
由于面向对象方法强调在软件开发过程
中面向客观世界(问题域)中的事物,
采用人类在认识世界的过程中普通运用
的思维方法,我们在认识面向对象的编
程时,需要了解面向对象的一些基本概
念,在介绍这些概念时力求与客观世界
和人的自然思维方式联系起来。
3.3.3 面向对象的编程( OOP)
⑴ 对象( Object)
? 对象( Object)是面向对象编程的最基
本的概念。
? 对象是系统中用来描述客观事物的一个
实体,它是构成系统的一个基本单元。
一个对象由一组属性( attribute)和对这
组属性进行操作的一组服务( Service)
组成。
3.3.3 面向对象的编程( OOP)
? 属性和服务,是构成对象的两个主要因素,其
定义是:
? 属性是用来描述对象静态特征的一个数据项。
? 服务是用来描述对象动态特征(行为)的一个
操作序列。
? 一个对象可以有多项属性和多项服务。一个对
象的属性和服务被结合成一个整体,对象的属
性值只能由这个对象的服务存取。
3.3.3 面向对象的编程( OOP)
? 另外需要说明以下两点:第一点是,对
象只描述客观事物本质的、与系统目标
有关的特征,而不考虑那些非本质的、
与系统目标无关的特征。这就是说,对
象是对事物的抽象描述。第二点是,对
象是属性和服务的结合体,二者是不可
分的;而且对象的属性值只能由这个对
象的服务来读取和修改,这就是封装概
念。
3.3.3 面向对象的编程( OOP)
? 根据以上两点,也可以给出如下对象定
义:
对象是问题域或实现域中某些事物的一
个抽象,它反映该事物在系统中需要保
存的信息和发挥的作用;它是一组属性
和有权对这些属性进行操作的一组服务
的封装体。
3.3.3 面向对象的编程( OOP)
⑵ 类 (class)
在 OO方法中, 类的定义是:
? 类是具有相同属性和服务的一组对象的集合,
它为属于该类的全部对象提供了统一的抽象描
述,其内部包括属性和服务两个主要部分。
? 在面向对象的编程语言中,类是一个独立的程
序单元,它应该有一个类名并包括属性说明和
服务说明两个主要部分。类的作用是定义对象。
比如,程序中给出了一个类的说明,然后以静
态声明或动态创建等方式定义它的对象实例。
3.3.3 面向对象的编程( OOP)
? 类与对象的关系如同一个模具与用这个模具铸
造出来的铸件之间的关系。类给出了属于该类
的全部对象的抽象定义,而对象则是符合这种
定义的一个实体。所以,一个对象又称作类的
一个实例( instance),而有的文献又把类称
作对象的模板( template)。所谓, 实体,,
,实例, 意味着什么呢?最现实的一件事是:
在程序中,每个对象需要有自己的存储空间,
以保存它自己的属性值。我们说同类对象具有
相同的属性与服务,是指它们的定义形式相同,
而不是说每个对象的属性值都相同
3.3.3 面向对象的编程( OOP)
? 事物(对象)既具有共同性,也具有特殊性。运用抽
象的原则舍弃对象的特殊性,抽取其共同性,则得到
一个适应一批对象的类。如果在这个类的范围内考虑
定义这个类时舍弃的某些特殊性,则在这个类中有一
部分对象具有这些特殊性,而这些对象彼此是共同的,
于是得到一个新的类。它是前一个类的子集,称作前
一个类的特殊类,而前一个类称作这个新类的一般类,
这是从一般类发现特殊类。也可以从特殊到一般:考
虑若干类所具有的彼此共同的特征,舍弃它们彼此不
同的特殊性,则得到这些类的一般类。
3.3.3 面向对象的编程( OOP)
? 一般类和特殊类是相对而言的,它们之
间是一种真包含的关系(即:一般类是
特殊类的一个真子集)。如果两个类之
间没有这种关系,就谈不上一般和特殊。
特殊类具有它的一般类的全部特征,同
时又具有一些只适应于本类对象的独特
特征。
3.3.3 面向对象的编程( OOP)
? 在 OO方法中关于一般类与特殊类的定义是:
如果类 A具有类 B的全部属性和全部服务,而且
具有自己特有的某些属性或服务,则 A叫做 B的
特殊类,B叫做 A的一般类。
? 这个定义也可用另一种方式给出:
如果类 A的全部对象都是类 B的对象,而且类 B
中存在不属于类 A的对象,则 A是 B的特殊类,B
是 A的一般类。
? 以上两个定义是等价的。但从软件开发的角度
看,前一个定义运用起来将更加方便。
3.3.3 面向对象的编程( OOP)
⑶ 封装( encapsulation)和信息隐蔽
( information hiding)
? 封装是面向对象方法的一个重要原则。它有两
个涵义是,把对象的全部属性和全部服务结合
在一起,形成一个不可分割的独立单位(即对
象)。第二个涵义也称作, 信息隐蔽,,即尽
可能隐蔽对象的内部细节,对外形成一个边界
(或者说形成一道屏障),只保留有限的对外
接口使之与外部发生联系。这主要是指对象的
外部不能直接地存取对象的属性,只能通过几
个允许外部使用的服务与对象发生联系。
3.3.3 面向对象的编程( OOP)
? 用比较简练的语言给出封装的定义就是:
封装就是把对象的属性和服务结合成一个独立
的系统单位,并尽可能隐蔽对象的内部细节。
? 封装是面向对象方法的一个原则,也是面向对
象技术必须提供的一种机制。例如在面向对象
的语言中,要求把属性和服务结合起来定义成
一个程序单位,并通过编译系统保证对象的外
部不能直接存取对象的属性或调用它的内部服
务。这种机制就叫作封装机制。
3.3.3 面向对象的编程( OOP)
? 与封装密切相关的一个术语是可见性。它是指
对象的属性和服务允许对象外部存取和引用的
程度。
? 我们已经讨论了封装的好处,然而封装也有它
的副作用。如果强调严格的封装,则对象的任
何属性都不允许外部直接存取,因此就要增加
许多没有其它意义,只负责读或写的服务。这
为编程工作增加了负担,增加了运行开销,并
且使程序显得臃肿。为了避免这一点,语言往
往采取一种比较现实的灵活态度 — 允许对象有
不同程度的可见性。
3.3.3 面向对象的编程( OOP)
⑷ 继承( inheritance)
? 继承是 OO方法中一个十分重要的概念,并且是 OO技
术可提高软件开发效率的重要原因之一,其定义是:
特殊类的对象拥有其一般类的全部属性与服务,称作
特殊类对一般类的继承。
? 继承意味着, 自动地拥有,,或, 隐含地复制, 。就
是说,特殊类中不必重新定义已在它的一般类中定义
过的属性和服务,而它却自动地、隐含地拥有其一般
类的所有属性与服务。 OO方法的这种特性称作对象的
继承性。从一般类和特殊类的定义可看到,后者对前
者的继承在逻辑上是必然的。继承的实现则是通过 OO
系统(例如 OOPL)的继承机制来保证的。
3.3.3 面向对象的编程( OOP)
? 继承对于软件复用是很益的。在开发一个系统
时,使特殊类继承一般类,这本身就是软件复
用,然而其复用意义不仅如此。如果把用 OO
方法开发的类作为可复用构件提交到构件库,
那么在开发新系统时不仅可以直接地复用这个
类,还可以把它作为一般类,通过继承而实现
复用,从而大大扩展了复用范围。
? 一个类可以是多个一般类的特殊类,它从多个
一般类中继承了属性与服务,这种继承模式叫
作多继承。多继承无论从概念上还是从技术上
都是单继承的推广。
3.3.3 面向对象的编程( OOP)
⑸ 消息 ( message)
? 对象通过它对外提供的服务在系统中发挥自己的作用。
当系统中的其它对象(或其它系统成分)请求这个对
象执行某个服务时,它就响应这个请求,完成指定的
服务所应完成的职责。在 OO方法中把向对象发出的服
务请求称作消息。通过消息进行对象之间的通信,也
是 OO方法的一个原则,它与封装的原则有密切的关系。
封装使对象成为一些各司其职,互不干扰的独立单位;
消息通信则为它们提供了唯一合法的动态联系途径,
使它们的行为能够互相配合,构成一个有机的运动的
系统。
3.3.3 面向对象的编程( OOP)
OO方法中对消息的定义是:
? 消息就是向对象发出的服务请求,它应该含有下述信
息:提供服务的对象标识、服务标识、输入信息和回
答信息。
? 消息的接收者是提供服务的对象。在设计时,它对外
提供的每个服务应规定消息的格式,这种规定称作消
息协议。
? 消息的发送者是要求提供服务的对象或其它系统成分
(在不要求完全对象化的语言中允许有不属于任何对
象的成分,例如 C++程序的 main函数)。在它的每个
发送点上需要写出一个完整的消息,其内容包括接收
者(对象标识)、服务标识和符合消息协议要求的参
数。
3.3.3 面向对象的编程( OOP)
? 对照一下某些 OO语言(如 C++,Object Pascal或 Eiffel)
对消息的实现,在这些语言中,所谓消息其实就是函
数(或过程、例程)调用。
? 作为 OO方法中的一个基本概念,采用, 消息, 这个术
语至少有以下好处:第一,更接近人们日常思维所采
用的术语;第二,其涵义更具有一般性,而不限制采
用何种实现技术。在分布式技术和客户 /服务器技术快
速发展的今天,对象可以在不同的网络结点上实现并
相互提供服务。在这种背景下可以看到,,消息, 这
个术语确实有些更强的适应性。
3.3.3 面向对象的编程( OOP)
⑹ 结构( Structure)与连接( connection)
? 仅仅用一些对象(以及它们的类)描述问题域中的事物是不够的。
因为任何一个较为复杂的问题域中,事物之间并不是互相孤立、
各不相关的,而是具有一定的关系,并因此构成一个有机的整体。
为了使系统能够有效地映射问题域,系统开发者需认识并描述对
象之间的以下几种关系:
? 对象的分类关系;
? 对象之间的组成关系;
? 对象属性之间的静态联系;
? 对象行为之间的动态联系。
? OO方法运用一般 — 特殊结构、整体 — 部分结构、实例连接和消息
连接描述对象之间的以上四种关系。以下分别加以介绍。
3.3.3 面向对象的编程( OOP)
① 一般 — 特殊结构
? 一般 — 特殊结构又称作分类结构( classification
structure),是由一组具有一般 — 特殊关系(继承关系)
的类所组成的结构。它是一个以类为结点,以继承关
系为边的连通有向图。其中,仅由一些存在单继承关
系的类形成的结构又称作层次结构( hierarchy
structure),它是一个以最上层的一般类为根的树形
结构;由一些存在多继承关系的类形成的结构又称作
网格结构( lattice structure),它是一个半序的连通
有向图。
? 下图是两个一般 — 特殊结构的例子,其中 (a)是一个层
次结构,(b)是一个网格结构。
3.3.3 面向对象的编程( OOP)
军人
军官 士兵
义务兵 志愿兵
交通工具
轮船 客运工具
客轮
汽车
发动机 车身
气缸
(a) (b)
3.3.3 面向对象的编程( OOP)
② 整体 — 部分结构
? 整体 — 部分结构又称作组装结构( composition
structure),它描述对象之间的组成关系,即:
一个(或一些)对象是另一个对象的组成或部
分。客观世界中存在许多这样的现象,例如,
发动机是汽车的一个组成部分。一个整体 — 部
分结构由一组彼此之间存在着这种组成关系的
对象构成,如上右图所示。
3.3.3 面向对象的编程( OOP)
? 整体 — 部分结构有两种实现方式。第一种方式
是用部分对象的类作为一种广义的数据类型来
定义整体对象的一个属性,构成一个嵌套对象。
在这种方式下,一个部分对象只能隶属于唯一
的整体对象,并与它同生同灭。第二种方式是
独立地定义和创建整体对象和部分对象,并在
整体对象中设置一个属性,它的值是部分对象
的对象标识,或者是一个指向部分对象的指针。
在这种方式下,一个部分对象可以属于多个整
体对象,并具有不同的生存期。后一种情况便
于表示比较松散的整体 — 部分关系。
3.3.3 面向对象的编程( OOP)
③ 实例连接
? 实例连接反映对象与对象之间的静态联
系。例如教师和学生之间的任课关系,
单位的公用汽车和驾驶员之间的使用关
系等等。这种双边关系在实现中可以通
过对象(实例)的属性表达出来。所以
这种关系称作实例连接。
3.3.3 面向对象的编程( OOP)
④ 消息连接
? 消息连接描述对象之间的动态联系,即:
若一个对象在执行自己的服务时,需要
(通过消息)请求另一个对象为它完成
某个服务,则说第一个对象与第二个对
象之间存在着消息连接。消息连接是有
向的,从消息发送者指向消息接收者。
3.3.3 面向对象的编程( OOP)
⑺ 多态性 ( polymorphism)
? 对象的多态性是指在一般类中定义的属
性或服务被特殊类继承之后,可以具有
不同的数据类型或表现出不同的行为。
这使得同一个属性或服务名在一般类及
其各个特殊类中具有不同的语义。
3.3.3 面向对象的编程( OOP)
? 如果一种 OOPL(面向对象的编程语言)
能支持对象的多态性,则可为开发者带
来不少方便。
3.3.3 面向对象的编程( OOP)
? 例如,在一般类, 几何图形, 中定义了一个服务, 绘
图,,但并不确定执行时到底画一个什么图形。特殊
类, 椭圆, 和, 多边形, 都继承了,但其功能几何图
形类的绘图服务却不同:一个是画出一个椭圆,一个
是画出一个多边形。进而,在多边形类更下层的一般
类, 矩形, 中绘图服务又可以采用一个比画一般的多
边形更高效和的算法来画一个矩形。这样,当系统的
其余部分请求画出任何一种几何图形时,消息中给出
的服务名同样都是, 绘图, (因而消息的书写方式可
以统一),而椭圆、多边形、矩形等类的对象接收到
这个消息时却各自执行不同的绘图算法。
3.3.3 面向对象的编程( OOP)
⑻ 永久对象 ( persistent object)
? 永久对象是当前 OO领域的一个技术热点。所谓
永久对象,就是生存期可以超越程序的执行时
间而长期存在的对象。
3.3.3 面向对象的编程( OOP)
? 目前大多数商品化的 OOPL是不支持永久对象的。程序
中定义的对象,其生存期都不超过程序的运行时间。
即当程序运行结束时,它所定义的对象也都消失了。
如果一个应用要求把某些对象的属性信息长期保存,
并能在下一次程序运行时加以恢复,就只好借助文件
系统或数据库管理系统来实现。这需要程序员做许多
工作,包括对象与文件(或数据库)之间数据格式的
转换,以及保存与恢复所需的操作。这些工作无疑是
很繁琐的,而且这意味着面向对象的概念的时空范围
只局限于程序运行时间和内存空间,一旦超出这个范
围,对象就变成了传统的外存数据。
3.3.3 面向对象的编程( OOP)
? 永久对象的概念及实现技术可以使上述问题得
到解决。只要程序员声明某个对象是永久的,
则它的存储、恢复、转换等问题一概不用程序
员关心,完全由系统自动解决。呈现在开发人
员面前的是一个, 无缝的, ( seamless)对象
概念。永久对象的意义不仅仅提高了编程效率,
它还使 OOD阶段的数据管理部分的设计大为简
化,而且可实现对象在不同程序之间的动态共
享
3.3.3 面向对象的编程( OOP)
? 永久对象的实现需要有较强的技术支持。它需要一个
能够描述和处理永久对象的编程语言。这种语言的实
现需要基于一个存储和管理永久对象的对象管理系统
( object management system,简称 OMS)。无论是支
持永久对象的 OOPL还是 OMS,其实现都有较大难度,需
要解决对象的存储、恢复、共享、并发存取、一致性
保护等一系列技术问题,所以目前国内外在这方面研
究性的工作较多而实用的产品较少。在我国,由北京
大学等 20多家单位通过, 八五, 科技攻关研制成功的
青鸟 Ⅱ 型系统( JB2)中已经实现了一个 OMS和一个支
持永久对象的 OOPL(叫作 CASE— C++语言),并用它开
发了近 20个软件工具。
3.3.3 面向对象的编程( OOP)
⑼ 主动对象 ( active object)
? 按照通常理解 OO概念,对象是一组属性和一组
服务的封装体。它的每个服务是一个在消息的
驱动下被动执行的操作。
3.3.3 面向对象的编程( OOP)
? 向对象发一个消息,它就响应这个消息
而执行被请求的服务,否则它的服务就
不执行。每个服务相当于过程式语言中
一个过程、函数或例程(在大多数 OOPL
中它的确就是一个等待被调用的过程、
函数或例程。 Smallatlk中称作, 方法,
而没有采用这些传统的术语,但本质上
并没有什么不同)。
3.3.3 面向对象的编程( OOP)
? 所有这样的对象都是被动对象( passive object),
需要通过消息的驱动(或者说通过消息的触发)才能
执行,那么,原始的驱动来自哪里?目前的 OOPL一般
是来自所有类定义之外的一段主程序,例如 C++中的
main函数。以纯 OO风格著称的 Smalltalk,也需要在所
有类定义之外写一段相当于主程序的源码,才能使系
统最终成为一个可运行的程序。这样做是不是纯 OO,
对实践者来说并不重要。特别是,当系统是一个顺序
程序时,做到这一点也没有太大的不便。
3.3.3 面向对象的编程( OOP)
? 在现实世界(问题域)中具有主动行为的事物并不罕
见。例如,交通控制系统中的信号灯,生产控制系统
中异步运行的设备等等。每个具有主动行为的事物在
系统中应该被设计成一个任务,因为它们的行为是主
动的,需要并发地执行。除此之外,在系统设计阶段
还可能因实现的要求而增加其它一些任务。由于任务
是一些主动的、彼此并发的执行单位,所以无法用被
动对象描述。为此,引入了主动对象的概念,在 OOD阶
段进行任务管理部分的设计时用主动对象表示每个任
务。
3.3.3 面向对象的编程( OOP)
其定义是:
主动对象是一组属性和一组服务的封装体, 其
中至少有一个服务不需要接收消息就能主动执
行 ( 称作主动服务 ) 。
? 主动对象的作用是描述问题域中具有主动行为
的事物以及在系统设计时识别的任务,它的主
动服务描述相应的任务所应完成的操作。在系
统实现阶段,主动服务应该被实现为一个能并
发执行的、主动的程序单位,例如进程或线程。
3.3.3 面向对象的编程( OOP)
? 引入主动对象概念解决了系统设计阶段对任务
的描述问题,从而为在实现阶段构造一个描述
多任务的并发程序提供了依据。但是这种依据
只能是编程工作的一个参考,因为目前还没有
商品化的 OOPL能支持主动对象的概念,所以
OOD阶段识别的主动对象无法直接地对应为程
序中的一个主动对象,需要程序员在现有的语
言条件下设法把它实现成一个主动成分。
3.3.3 面向对象的编程( OOP)
? 面向对象的编程语言( OOPL)与已往各种语言的根本
不同是,它的设计出发点就是为了更直接地描述问题
域中客观存在的事物(即对象)以及它们之间的关系,
主要体现在以下几点:
⑴ 客观世界(问题域)是由一些具体的事物构成的。每
个事物具有自己的静态特征(即可以由一组数据表示
的特征)和动态特征(事物的行为或功能,即可以由
一组操作表示的特征)。
OOPL用对象描述问题域中的事物,每个对象由一组属
性和一组服务构成,分别描述事物的静态特征和动态
特征。
3.3.3 面向对象的编程( OOP)
⑵ 客观世界中的事物既具有共同性又具有特殊性。
人类认识客观世界的基本方法之一是对事物进
行分类,即:根据事物的共同性把事物归结为
某些类;考虑一个类中部分事物的特殊可得到
这个类的子类,子类既具有父类的共同性又具
有自己的特殊性。
OOPL用类表示一组具有相同的属性和服务的
对象,并通过继承机制保证子类具有父类的全
部属性和服务。
3.3.3 面向对象的编程( OOP)
⑶ 客观世界中较为复杂的事物往往是由其
它一些比较简单的事物构成的,例如一
架飞机由机舱、机翼和发动机构成。
OOPL中提供了描述这种组成关系的结构
(一般 — 特殊结构、整体 — 部分结构
等)。
3.3.3 面向对象的编程( OOP)
(4) 客观世界中的一个事物可能与其它事物
存在某种行为上的联系。例如:采购员
购入一次货物要引起会计的一次帐目处
理。
OOPL通过消息表示对象之间的动态联系。
3.3.3 面向对象的编程( OOP)
? 由以上几点可以看出,面向对象的编程语言使
程序能够比较直接地反映客观世界的本来面目,
并且使软件开发人员能够运用人类认识事物所
采用的一般思维方法来进行软件开发。面向对
象的语言和人类认识、理解客观世界所使用的
自然语言之间的距离是比较小的。当然,二者
之间仍然存在着一定的距离。自然语言的丰富
多样和借助人脑的联想思想才能辨别的语义,
仍是目前任何一种计算机编程语言无法企及的。
3.3.3 面向对象的编程( OOP)
? 如图 3.7表示随着编程语言由低级向高级的发
展,它们与自然语言之间的鸿沟在逐渐变窄。
开发人员从对问题域产生正确的认识,到用一
种编程语言把这些认识描述出来所付出的劳动
(以及其中可能发生的错误),随着语言鸿沟
的变窄而减少;由机器代替人完成的工作则随
着语言鸿沟的变窄而增多。这正是计算机语言
(以及整个计算机科学)发展的大趋势。
3.3.3 面向对象的编程( OOP)
? 编程语言到计算机之间的深色阴影表示
这部分工作是由机器自动完成的,基本
不需要开发人员花费精力了。自然语言
和编程语言中间的空白区域表示语言的
鸿沟,它表明从人们借助自然语言对问
题域有一个正确认识,到用一种编程语
言正确地表达出来,其间所存在的差距。
而面向对象的语言使这条鸿沟变窄,但
仍有一些距离。
3.4 编程前的准备
? 为了保证开发成果的质量,提高开发效
率,防止错误发生,在实际进行程序编
制之前应作如下方面的准备。
⑴ 制定标准(工作标准和编程基准);
⑵ 知识共享;
⑶ 共享数据准备;
⑷ 综合利用开发环境;
⑸ 注意开发环境与实际应用环境的差异。
3.4.1 确定标准
? 实际编程工作开始前、为了保证开发成果的质
量,系统的开发环境和标准化的工作流程应该
有机地结合起来,把编程作业从头到尾的过程
归纳为标准化的模式,开发者都必须按照这个
标准化模式进行工作,这样可以抑制和防止最
终开发成果因人而异造成的差异,防止错误发
生,提高生产效率,确保程序编制的质量。在
项目开发之前,从事开发工作的管理者必须把
业务工作的次序、流程和最终开发成果的格式
按标准化模式作出开发基准,以取得一致的开
发成果。
3.4.1 确定标准
1、工作标准的制定
? 在准备阶段,所制定的工作标准包含的
内容有:详细设计书的标准、程序设计
的标准以及共有资源利用的规定,如图
3.8所示。
3.4.1 确定标准
? 值得 注意 的是,要根据客户的要求、检
查自己制定的开发标准与客户提出的开
发标准是否一致,决定是选用客户的开
发标准或者采用自己的开发标准。工作
标准的制定和整理是从事工程管理的管
理者的重要任务,程序员必须认识到它
的必要性,严格地按照每一步工作流程
进行开发,细心地遵守每一条开发标准。
3.4.1 确定标准
2、编码标准的制定
? 首先需要明确的是,程序员的创造性发挥,不
在于其个人独特的编码风格和独特的编码技巧,
而应该是统一风格、统一技巧,在减少程序间
品质的差异性、降低程序的出错率、严守工程
工期方面下工夫。同时,制定编码标准还有其
它的重要意义,它可以使全体程序员都遵守同
样的编码标准,排除个别程序员以自己的才能
去理解编码习惯和技巧,增强程序的可读性和
可维护性,使程序质量在一定程度上得到保障。
图 3.9给出制定编码标准的内容。
3.4.2 知识共享的准备
? 使用新技术的开发过程中,为了避免程
序编制技能的不平衡,有必要对开发人
员进行统一培训,因此培训教育计划也
作为项目开发的一部分。项目开始后发
生的各种问题以及问题的解决方法要作
为共通问题通报给各个开发小组,这样
以防止同样的错误再发生。
3.4.2 知识共享的准备
1、事前的人员教育
? 在软件项目开发之前,除了充分利用现有技术
和开发经验外,还须对开发人员进行教育,教
育内容包括两个方面,一个方面是为了适应当
前工作的需要,进行个别的开发案例的技术教
育;另一个方面作为人才的长期培养,需要进
行作为基础能力的技术教育(如图 3.10所示)。
这些培训教育都要作出相应的培训教育计划。
3.4.2 知识共享的准备
2、知识共享
? 所谓共享的知识,在开发环境中有通用的技能
和项目特有的资源两种。 所谓通用技能,是指
本项目开发和在其他项目里使用同一工具进行
开发时的成功经验。把通用技能和有关项目特
有的资源,积蓄在同一个数据库里,最好是由
经验丰富的骨干系统工程师,以知识数据库管
理者的立场,把项目特有的资源抽象化,转换
成通俗易懂的技能积蓄起来,这样便于大家知
识共享和参照,关于知识共享的准备如图 3.11
所示。
3.4.3 共享数据的准备
? 编程工作开始前,必须构筑全部程序员
共享的数据库等资源,集中管理这些共
享资源的场所叫做数据库。数据库里必
须准备的项目是内部设计时作为共享资
源定义的全部项目。如果设计书没有指
出,在编程工作展开时也要列举出必要
的资源并做好相应的准备。
3.4.3 共享数据的准备
? 共享数据准备的内容有:
① 开发测试用的用户登录的帐号。
② 数据库的安装。
·数据库接口定义;
·全领域(数据领域,Log日志领域、索引领域等)
的长度定义;
·作成各领域的物理文件、物理盘分配的定义;
·详细层的数据定义(全索引各 TABLE,COLUMN、
VIEW等);
·建立数据结构之间的关系。
3.4.3 共享数据的准备
③ 通用子程序、类库的封装。
·在现有子程序、类库的功能的调查基础上
确定可利用的通用子程序和类库;
·新建子程序的粒度定义。从功能的观点决
定子程序到哪层为止;是否分割、是否
综合、能否归纳到 1个类库中;
·通用子程序、类库实装
3.4.3 共享数据的准备
④ 出错处理体系化
·出错内容的整理。参照现行系统整理错误内容;
·错误处理的分类;
·异常处理类的设计;
·错误信息标准化(决定错误信息的编号体系、决
定错误信息的分类显示方法、错误信息的格式
定义以及错误信息格式定义的例子);
·错误信息显示处理的实现(把错误信息的显示处
理作成通用的子程序)。
3.4.3 共享数据的准备
⑤ 全局变量、常量
·整理出必要的全局变量、全局常量;
·全局变量、常量的命名。
3.4.4 综合利用开发环境
? 在综合利用开发环境方面,我们可以将
编程过程划分为,Coding(编码 ),
Debug(调试 )两个阶段,
3.4.4 综合利用开发环境
? 关于综合开发环境的功能详见图
3.4.4 综合利用开发环境
⑴ 版本的统一
? 开发组在应用同一综合开发环境的时候,应事先统一
版本,如果版本不完全一致的话,执行模块及动态链
接库工作时就会产生异常。此外,子程序也可能在不
断更新换代,所以,应尽可能利用加载了最新子程序
的测试环境。
⑵ 用户设定的统一
? 尽管多数开发环境都允许用户自由设定显示颜色,嵌
套格式等部分内部参数,但为了严格遵守编程标准,
应事先对 (这些环境的 )用户设定进行统一。实际上,由
于可能有多个程序员使用 1台 PC(开发设备 ),所以最好
事先使开发环境一致,这样才能保证其安全运行。
第三章 编程工程
3.1.1 编程工程的定义
? 编程工程 就是用程序设计语言把程序设
计的结果和过程翻译为在计算机相应环
境下可运行的软件产品,把系统工程师
按照用户需求设计出来的系统构架变为
真正可运行的软件系统的工程。
3.1.1 编程工程的定义
? 编程工程的作业内容 详细地划分为制定
工作标准,制定编码基准,理解设计书,
程序编码,自查,送上级系统工程师审
查,修改以及进行单元测试等若干步骤,
3.1.1 编程工程的定义
? 编程工程的作业流程
见 P12 图 2.3
3.1.2 易读易懂的程序
? 结构化编程以前,以个人为中心的编程作业
? 程序的规模逐渐扩大,产生了组织行为的软件
开发,而且产生了对过去开发的程序进行修改
后再利用的需求
? Goto语句的使用
? 能够把猛一看很大的很复杂的程序用单纯的方
法分解,分解后的一块一块的程序也都很单纯,
这就是, 易读易懂的程序, 。
3.2 结构化编程
? 结构化开发 --结构化分析、结构化设计和
结构化编程三个阶段
3.2.1 结构化开发过程
结构化编程
结构化设计
结构化分析
需求分析 /
验收测试计划
外部设计 /
系统测试计划
内部设计 /
组合测试计划
程序制造
(编码 &单元测试 )
验收测试
组合测试
系统测试
3.2.1 结构化开发过程
1、结构化分析
? 结构化分析方法的核心是沿数据流程图自顶向
下、逐步求精,是最经典的面向数据流的需求
分析方法。结构化分析方法使用系统流程图、
数据流程图、数据字典,ER图、处理说明等工
具来描述系统的功能需求、数据需求、运行需
求和系统扩充需求。该方法广泛应用于银行,
证券,商务处理,生产管理等大中型信息管理
系统的需求分析过程。
3.2.1 结构化开发过程
? 在软件系统开发的初期阶段,首先要对
用户的现行业务运行系统进行调查和现
状分析,把握用户对新的开发系统的要
求和希望,从用户提供的基本信息中,
整理出开发系统目的和可能实现的功能
范围,设计出新系统的数据流程图
( DFD,Data Flow Diagram),显示屏
幕关连图和功能概要说明书。
3.2.1 结构化开发过程
2、结构化设计
? 结构化设计方法通常也叫做面向数据流的设计、
面向行为的设计。结构化设计方法是以需求分
析阶段获得的新系统的数据流程图 (DFD)和显
示屏幕关连图为基础,通过一系列映射,自顶
向下,逐步细化,把它们变换为具体的程序概
要结构图和屏幕设计式样,把一个个复杂的问
题分解细化为由多个功能模块组成的具有层次
结构的软件系统。
3.2.1 结构化开发过程
3、结构化程序制造
? 结构化程序制造由结构化程序设计和结构化程
序编码组成,它以外部设计和内部设计过程中
获得的软件结构图及其相关设计资料为基础,
采用自顶向下,逐步细化的方法,把一个个模
块的功能逐步分解,细化为一系列具体的步骤,
作出结构化程序设计说明书,程序员再按照程
序设计说明书和系统设计的相关资料,把一步
步的处理说明翻译成一系列用某种程序设计语
言编写的程序代码。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 结构化分析、设计的成果文档
系统功能概要说明书 程序名称一览表
业务处理概要图( ER图) 公共子程序设计说明书
显示屏幕关连 图程序功能结构图
屏幕设计式样书 程序设计说明书
数据库设计说明书 程序处理追加功能说明书
代码设计说明书 模块功能的定义说明书
输入/输出文件设计说明书 输入数据检查说明书
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 在进行程序编码工作的初期,程序员首
先要获取系统功能概要说明书、业务处
理概要图( DFD图或者 ER图)、显示屏
幕关连图和程序名称一览表,理解开发
系统的目的、整体要素和各个子系统的
处理要求。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 程序编码的主要依据是程序设计说明书,在编
写程序代码之前,程序员首先要确认自己所要
编制的程序名称,获取该程序的程序设计说明
书,理解该程序的程序功能概要和各个模块的
详细处理说明,确定该程序所要使用的屏幕和
报表的名称,数据库表和输入输出文件的名称,
以及调用公共子程序的名称,找出所有相关的
设计资料,充分理解程序设计说明书的内容,
若有疑问或不明白的地方,要提出问题,与系
统设计人员进行交流确认。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 在正确理解程序设计说明书的基础上,
构思出结构化程序的框架,必要时作出
程序处理流程图。使用 C语言或者其它语
言编写程序代码时,还要获取相关文件
和 DB的格式定义代码( *.h)或 COPY句,
确认各个数据项目的变量名称。需要调
用公共子程序时,要获得公共子程序的
代码或者可执行文件,做好输入输出参
数的设置和返回值的判断处理。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 在编写程序代码之前,还需要获得编码
测试基准、共通处理说明书和代码设计
说明书、获取相应的例子程序,在正确
理解编码测试基准的基础上,进行程序
编码和编码完成后的单元测试,一定不
要在程序编码测试完成以后,再回过头
来对照编程基准和共通处理说明书,检
查修改与基准不一致的地方,那样既增
加了作业时间又不能保证程序质量。
3.2.3 结构化编码
? 程序代码的质量与软件系统外部设计和
内部设计的质量直接相关,同时,程序
设计语言的特性和程序员的编码水平,
程序代码的可读性,可维护性,可靠性,
可测试性都是直接影响程序质量的因素。
3.2.2 系统分析和系统设计的
成果文档与编程的关系
? 在进行组合测试之前,需要获取系统功
能概要说明书、数据流程图、编码测试
基准和共通处理说明书,把握各个子系
统的处理流程和各个程序单元之间的接
口,确保实现整个系统的设计功能
3.2.3 结构化编码
? 结构化编码采用自顶向下,逐步细化的
方法,先全局,后局部,先整体,后细
节,先抽象,后具体,逐步求精,编制
出来的程序具有清晰的逻辑层次结构,
容易阅读、理解、修改和维护,可以提
高软件质量,提高软件开发的成功率和
生产性。结构化编码过程中,要遵循以
下几个主要的原则:
3.2.3 结构化编码
⑴ 尽可能使用语言提供的基本控制结构,顺序结构、选
择结构和重复结构。
⑵ 选用的控制结构只准许有一个入口和一个出口。
⑶ 利用程序内部函数,把程序组织成容易识别的内部函
数模块,每个模块只有一个入口或一个出口,一般不
超过 200行。
⑷ 复杂结构应该用基本控制结构组合或嵌套来实现。
⑸ 尽可能减少 GOTO语句的使用,一般限制用到以下两
种情况:
? 把控制转移到出错处理。
? 把控制转移到函数模块结束
3.2.3 结构化编码
? 大量采用 GOTO语句实现控制路径,会使
程序路径变得复杂而且混乱,但有时完
全不用 GOTO语句,可能会增加程序实现
的复杂度。例如,在查找结束时、文件
访问结束时或出现错误情况要从循环中
转出时,使用 GOTO语句会使程序更加清
晰易懂。所以,应该加以限制地使用
GOTO语句。
3.2.3 结构化编码
? 例如,使用 C语言编写下面的一个小程序,
目的是打印出 A,B,C三个数据中的最小
数,如图 3.2给出了程序流程图。
? 程序段 1、程序段 2 比较
3.2.3 结构化编码
? 结构化程序编码就是按照结构化程序设
计说明书,从程序的控制结构入手,自
顶向下,逐步细化,把一个个模块的功
能逐步分解,细化为一系列具体的步骤。
3.2.3 结构化编码
? 在结构化程序的实现方法中,有两种常
用的基本方法,第一是 BREAK处理(见
图 3.3),第二是 MATCHING处理(见图
3.5)
3.2.3 结构化编码
BREAK方法的处理概要如下,处理流程见图 3.4:
① 按关键字项目值的升序读入输入文件的记录,
把关键字项目的值存入工作变量中。
② 关键字项目的值相同时,进行统计处理(或者
其他处理)。
③ 关键字项目的值发生了变化( BREAK)的时候,
把变化前( BREAK BEFOR)的关键字项目值和
统计结果输出到文件中(或者其他处理),用
变化后( BREAK AFTER)的关键字项目值替换
变化前的关键字项目值。
3.2.3 结构化编码
④ 读入输入文件的下一条记录,把关键字
项目的值存入变化后的工作变量中。
⑤ 继续进行上述②至④的处理,直至文件
读入结束。
3.2.3 结构化编码
? 前提条件是:
在进行 BREAK处理之前,输入文件必须
是已经按照关键字项目值进行排序(升
序或者降序)处理好的。
3.2.3 结构化编码
MATCHING方法处理概要说明如下,处理流程如
图 3.6所示。
① 按关键字项目值的升序读入基础文件的记录,
把关键字项目的值存入基础 KEY工作变量中。
② 按关键字项目值的升序读入事务文件的记录,
把关键字项目的值存入事务 KEY工作变量中。
③ 基础 KEY的值与事务 KEY值相等时,把事务文
件的数据编辑输出到文件中。读入事务文件的
下一条记录,把关键字值存入事务 KEY。
3.2.3 结构化编码
④ 基础 KEY的值大于事务 KEY值的时候,把事务 KEY的值
写到错误信息文件中。读入事务文件的下一条记录,
把关键字值存入事务 KEY。
⑤ 基础 KEY的值小于事务 KEY值的时候,读入基础文件的
下一条记录,把关键字值存入基础 KEY。
⑥ 继续进行上述③至④的处理,直至文件读入结束。
1:1的匹配处理的情况下,上述处理③读入事务文件的同
时,还要读入基础文件
3.2.3 结构化编码
? 前提条件是:
在进行 MATCHING处理之前,输入文件
必须是已经按照关键字项目的值进行排
序(升序或者降序)处理好的。
3.3.1 什么是面向对象
? 面向对象 (object-oriented或 object-
orientation)不仅是一些具体的软件开发
技术与策略,而且是一整套关于如何看
待软件系统与现实世界的关系,以什么
观点来研究问题并进行求解,以及如何
进行系统构造的软件方法学。
3.3.1 什么是面向对象
? 概括地说,面向对象方法的基本思想是,从现实世界
中客观存在的事物(即对象)出发来构造软件系统,
并在系统构造中尽可能运用人类的自然思维方式。
? 开发一个软件是为了解决某些问题,这些问题所涉及
的业务范围称作该软件的问题域。面向对象方法强调
直接以问题域(现实世界)中的事物为中心来思考问
题、认识问题,并根据这些事物的本质特征,把它们
抽象地表示为系统中的对象,作为系统的基本构成单
位(而不是用一些与现实世界中的事物相差较远,并
且没有对应关系的其它概念来构造系统)。这可以使
系统直接地映射问题域,保持问题域中事物及其相互
关系的本来面貌。
3.3.1 什么是面向对象
? 自 80年代末期到 90年代,面向对象的方
法与技术向着软件生命周期的前期阶段
发展,即:人们对面向对象方法的研究
与运用,不再局限于编程阶段,而是从
系统分析和系统设计阶段就开始采用面
向对象方法。这标志着面向对象方法已
经发展成一种完整的方法论和系统化的
技术体系
3.3.1 什么是面向对象
? 面向对象的方法与技术发展到软件生命周期的
前期阶段有着更为深刻的意义。因为面向对象
方法的本质,就是主张从客观世界固有的事物
出发来构造系统,提倡用人类在现实生活中常
用的思维方法来认识、理解和描述客观事物,
强调最终建立的系统能够映射问题域,即:系
统中的对象以及对象之间的关系能够如实地反
映问题域中固有事物及其关系。这恰恰是从分
析和设计阶段入手才能根本解决的问题。
3.3.2 面向对象的软件工程方法
? 面向对象的软件工程方法是面向对象方
法在软件工程领域的全面运用。它包括
面向对象的分析、面向对象的设计、面
向对象的编程、面向对象的测试和面向
对象的软件维护 (OOSM)等主要内容。
3.3.2 面向对象的软件工程方法
? 软件开发是对问题求解的过程。按照软
件工程学对软件生命周期的划分,软件
开发过程包括分析、设计、编程、测试
和维护等主要阶段。从认识论的角度看,
整个软件开发过程又可归结为两项主要
活动,即:人们对所要解决的问题及其
相关事物的认识和基于这种认识所进行
地描述。
3.3.2 面向对象的软件工程方法
? 粗略地划分认识与描述,可以把分析与设计看
作对问题及其解决方案的认识,把编程看作对
解决方案的描述。细致地划分,则分析和设计
阶段本身也包括描述,即按一定的软件开发模
型中分析及设计阶段的表示方法,产生分析文
档和设计文档;编程阶段也包括一定的认识和
理解活动,特别是在传统的软件开发方法中,
分析文档和设计文档不能很好地映射问题域,
程序员在书写程序之前,往往需要在分析、设
计文档的帮助下,对程序所要描述的事物进行
再认识。
3.3.2 面向对象的软件工程方法
? 对问题域的正确认识是软件开发工作的
首要任务。没有对问题域的正确认识,
就不可能产生一个正确的系统。描述只
是把开发人员对问题域的认识表达出来,
最终产生一个机器能够理解和执行的系
统实现。
3.3.2 面向对象的软件工程方法
? 既然软件开发是对问题域的认识和描述,按软
件工程学的观点,从认识事物方面看,它在分
析阶段提供了一些对问题域的分析认识方法。
从描述事物方面看,它在分析和设计阶段提供
了一些从问题域逐步过渡到编程语言的描述手
段。但是在结构化的软件工程方法中,这些过
渡手续并不连续。就是说,并没有完全填平语
言之间的鸿沟(如下图)。而在面向对象的开
发中,它们都是紧密衔接的,填平了语言之间
的鸿沟(如下图)。
传统的软件工程方法与面向对象
的软件工程方法
问题域
需求分析
总体设计
详细设计
编程
测试
计算机
自然语言
分析与设计的鸿沟
编程语言
问题域
OOA
(面向对象分析 )
OOD
(面向对象设计 )
OOP
(面向对象编程 )
OOT
(面向对象测试 )
计算机
自然语言
面向对象的编程语
言
3.3.3 面向对象的编程( OOP)
? 面向对象的编程又称作面向对象的实现( OOI)。它
是面向对象方法从诞生、发展到走向成熟的第一片领
地,也是使面向对象的软件开发最终实现的重要阶段。
在 OOA和 OOD理论出现之前,程序员要写一个好的面
向对象的程序,首先要学会运用 OO方法来认识问题域,
所以 OOP被看作一门比较高深的技术。现在,在
OOA→ OOD→ OOP这一软件工程的过程系列中,OOP
的分工比较简单了:认识问题域与设计系统成分的工
作已经在 OOA与 OOD阶段完成,OOP工作就是用同一
种面向对象的编程语言把 OOD模型中的每个部分书写
出来。
3.3.3 面向对象的编程( OOP)
? 我们使用的编程语言直接影响我们观察(建模)
现实的方式。 20世纪 70年代当我们使用 C、
Pascal和 PL/1等编程语言时,我们使用命令式
范围(即结构化方法)对现实建模。 20世纪 80
年代当我们使用关系数据库,SQL和 4GL时,
我们使用数据建模范型对现实建模 — 实体 — 关
系图。今天我们使用 C++,JAVA,Smalltalk和
Objective C编程时,我们使用面向对象的模型
对现实建模。
3.3.3 面向对象的编程( OOP)
? 面向对象编程的基本概念
由于面向对象方法强调在软件开发过程
中面向客观世界(问题域)中的事物,
采用人类在认识世界的过程中普通运用
的思维方法,我们在认识面向对象的编
程时,需要了解面向对象的一些基本概
念,在介绍这些概念时力求与客观世界
和人的自然思维方式联系起来。
3.3.3 面向对象的编程( OOP)
⑴ 对象( Object)
? 对象( Object)是面向对象编程的最基
本的概念。
? 对象是系统中用来描述客观事物的一个
实体,它是构成系统的一个基本单元。
一个对象由一组属性( attribute)和对这
组属性进行操作的一组服务( Service)
组成。
3.3.3 面向对象的编程( OOP)
? 属性和服务,是构成对象的两个主要因素,其
定义是:
? 属性是用来描述对象静态特征的一个数据项。
? 服务是用来描述对象动态特征(行为)的一个
操作序列。
? 一个对象可以有多项属性和多项服务。一个对
象的属性和服务被结合成一个整体,对象的属
性值只能由这个对象的服务存取。
3.3.3 面向对象的编程( OOP)
? 另外需要说明以下两点:第一点是,对
象只描述客观事物本质的、与系统目标
有关的特征,而不考虑那些非本质的、
与系统目标无关的特征。这就是说,对
象是对事物的抽象描述。第二点是,对
象是属性和服务的结合体,二者是不可
分的;而且对象的属性值只能由这个对
象的服务来读取和修改,这就是封装概
念。
3.3.3 面向对象的编程( OOP)
? 根据以上两点,也可以给出如下对象定
义:
对象是问题域或实现域中某些事物的一
个抽象,它反映该事物在系统中需要保
存的信息和发挥的作用;它是一组属性
和有权对这些属性进行操作的一组服务
的封装体。
3.3.3 面向对象的编程( OOP)
⑵ 类 (class)
在 OO方法中, 类的定义是:
? 类是具有相同属性和服务的一组对象的集合,
它为属于该类的全部对象提供了统一的抽象描
述,其内部包括属性和服务两个主要部分。
? 在面向对象的编程语言中,类是一个独立的程
序单元,它应该有一个类名并包括属性说明和
服务说明两个主要部分。类的作用是定义对象。
比如,程序中给出了一个类的说明,然后以静
态声明或动态创建等方式定义它的对象实例。
3.3.3 面向对象的编程( OOP)
? 类与对象的关系如同一个模具与用这个模具铸
造出来的铸件之间的关系。类给出了属于该类
的全部对象的抽象定义,而对象则是符合这种
定义的一个实体。所以,一个对象又称作类的
一个实例( instance),而有的文献又把类称
作对象的模板( template)。所谓, 实体,,
,实例, 意味着什么呢?最现实的一件事是:
在程序中,每个对象需要有自己的存储空间,
以保存它自己的属性值。我们说同类对象具有
相同的属性与服务,是指它们的定义形式相同,
而不是说每个对象的属性值都相同
3.3.3 面向对象的编程( OOP)
? 事物(对象)既具有共同性,也具有特殊性。运用抽
象的原则舍弃对象的特殊性,抽取其共同性,则得到
一个适应一批对象的类。如果在这个类的范围内考虑
定义这个类时舍弃的某些特殊性,则在这个类中有一
部分对象具有这些特殊性,而这些对象彼此是共同的,
于是得到一个新的类。它是前一个类的子集,称作前
一个类的特殊类,而前一个类称作这个新类的一般类,
这是从一般类发现特殊类。也可以从特殊到一般:考
虑若干类所具有的彼此共同的特征,舍弃它们彼此不
同的特殊性,则得到这些类的一般类。
3.3.3 面向对象的编程( OOP)
? 一般类和特殊类是相对而言的,它们之
间是一种真包含的关系(即:一般类是
特殊类的一个真子集)。如果两个类之
间没有这种关系,就谈不上一般和特殊。
特殊类具有它的一般类的全部特征,同
时又具有一些只适应于本类对象的独特
特征。
3.3.3 面向对象的编程( OOP)
? 在 OO方法中关于一般类与特殊类的定义是:
如果类 A具有类 B的全部属性和全部服务,而且
具有自己特有的某些属性或服务,则 A叫做 B的
特殊类,B叫做 A的一般类。
? 这个定义也可用另一种方式给出:
如果类 A的全部对象都是类 B的对象,而且类 B
中存在不属于类 A的对象,则 A是 B的特殊类,B
是 A的一般类。
? 以上两个定义是等价的。但从软件开发的角度
看,前一个定义运用起来将更加方便。
3.3.3 面向对象的编程( OOP)
⑶ 封装( encapsulation)和信息隐蔽
( information hiding)
? 封装是面向对象方法的一个重要原则。它有两
个涵义是,把对象的全部属性和全部服务结合
在一起,形成一个不可分割的独立单位(即对
象)。第二个涵义也称作, 信息隐蔽,,即尽
可能隐蔽对象的内部细节,对外形成一个边界
(或者说形成一道屏障),只保留有限的对外
接口使之与外部发生联系。这主要是指对象的
外部不能直接地存取对象的属性,只能通过几
个允许外部使用的服务与对象发生联系。
3.3.3 面向对象的编程( OOP)
? 用比较简练的语言给出封装的定义就是:
封装就是把对象的属性和服务结合成一个独立
的系统单位,并尽可能隐蔽对象的内部细节。
? 封装是面向对象方法的一个原则,也是面向对
象技术必须提供的一种机制。例如在面向对象
的语言中,要求把属性和服务结合起来定义成
一个程序单位,并通过编译系统保证对象的外
部不能直接存取对象的属性或调用它的内部服
务。这种机制就叫作封装机制。
3.3.3 面向对象的编程( OOP)
? 与封装密切相关的一个术语是可见性。它是指
对象的属性和服务允许对象外部存取和引用的
程度。
? 我们已经讨论了封装的好处,然而封装也有它
的副作用。如果强调严格的封装,则对象的任
何属性都不允许外部直接存取,因此就要增加
许多没有其它意义,只负责读或写的服务。这
为编程工作增加了负担,增加了运行开销,并
且使程序显得臃肿。为了避免这一点,语言往
往采取一种比较现实的灵活态度 — 允许对象有
不同程度的可见性。
3.3.3 面向对象的编程( OOP)
⑷ 继承( inheritance)
? 继承是 OO方法中一个十分重要的概念,并且是 OO技
术可提高软件开发效率的重要原因之一,其定义是:
特殊类的对象拥有其一般类的全部属性与服务,称作
特殊类对一般类的继承。
? 继承意味着, 自动地拥有,,或, 隐含地复制, 。就
是说,特殊类中不必重新定义已在它的一般类中定义
过的属性和服务,而它却自动地、隐含地拥有其一般
类的所有属性与服务。 OO方法的这种特性称作对象的
继承性。从一般类和特殊类的定义可看到,后者对前
者的继承在逻辑上是必然的。继承的实现则是通过 OO
系统(例如 OOPL)的继承机制来保证的。
3.3.3 面向对象的编程( OOP)
? 继承对于软件复用是很益的。在开发一个系统
时,使特殊类继承一般类,这本身就是软件复
用,然而其复用意义不仅如此。如果把用 OO
方法开发的类作为可复用构件提交到构件库,
那么在开发新系统时不仅可以直接地复用这个
类,还可以把它作为一般类,通过继承而实现
复用,从而大大扩展了复用范围。
? 一个类可以是多个一般类的特殊类,它从多个
一般类中继承了属性与服务,这种继承模式叫
作多继承。多继承无论从概念上还是从技术上
都是单继承的推广。
3.3.3 面向对象的编程( OOP)
⑸ 消息 ( message)
? 对象通过它对外提供的服务在系统中发挥自己的作用。
当系统中的其它对象(或其它系统成分)请求这个对
象执行某个服务时,它就响应这个请求,完成指定的
服务所应完成的职责。在 OO方法中把向对象发出的服
务请求称作消息。通过消息进行对象之间的通信,也
是 OO方法的一个原则,它与封装的原则有密切的关系。
封装使对象成为一些各司其职,互不干扰的独立单位;
消息通信则为它们提供了唯一合法的动态联系途径,
使它们的行为能够互相配合,构成一个有机的运动的
系统。
3.3.3 面向对象的编程( OOP)
OO方法中对消息的定义是:
? 消息就是向对象发出的服务请求,它应该含有下述信
息:提供服务的对象标识、服务标识、输入信息和回
答信息。
? 消息的接收者是提供服务的对象。在设计时,它对外
提供的每个服务应规定消息的格式,这种规定称作消
息协议。
? 消息的发送者是要求提供服务的对象或其它系统成分
(在不要求完全对象化的语言中允许有不属于任何对
象的成分,例如 C++程序的 main函数)。在它的每个
发送点上需要写出一个完整的消息,其内容包括接收
者(对象标识)、服务标识和符合消息协议要求的参
数。
3.3.3 面向对象的编程( OOP)
? 对照一下某些 OO语言(如 C++,Object Pascal或 Eiffel)
对消息的实现,在这些语言中,所谓消息其实就是函
数(或过程、例程)调用。
? 作为 OO方法中的一个基本概念,采用, 消息, 这个术
语至少有以下好处:第一,更接近人们日常思维所采
用的术语;第二,其涵义更具有一般性,而不限制采
用何种实现技术。在分布式技术和客户 /服务器技术快
速发展的今天,对象可以在不同的网络结点上实现并
相互提供服务。在这种背景下可以看到,,消息, 这
个术语确实有些更强的适应性。
3.3.3 面向对象的编程( OOP)
⑹ 结构( Structure)与连接( connection)
? 仅仅用一些对象(以及它们的类)描述问题域中的事物是不够的。
因为任何一个较为复杂的问题域中,事物之间并不是互相孤立、
各不相关的,而是具有一定的关系,并因此构成一个有机的整体。
为了使系统能够有效地映射问题域,系统开发者需认识并描述对
象之间的以下几种关系:
? 对象的分类关系;
? 对象之间的组成关系;
? 对象属性之间的静态联系;
? 对象行为之间的动态联系。
? OO方法运用一般 — 特殊结构、整体 — 部分结构、实例连接和消息
连接描述对象之间的以上四种关系。以下分别加以介绍。
3.3.3 面向对象的编程( OOP)
① 一般 — 特殊结构
? 一般 — 特殊结构又称作分类结构( classification
structure),是由一组具有一般 — 特殊关系(继承关系)
的类所组成的结构。它是一个以类为结点,以继承关
系为边的连通有向图。其中,仅由一些存在单继承关
系的类形成的结构又称作层次结构( hierarchy
structure),它是一个以最上层的一般类为根的树形
结构;由一些存在多继承关系的类形成的结构又称作
网格结构( lattice structure),它是一个半序的连通
有向图。
? 下图是两个一般 — 特殊结构的例子,其中 (a)是一个层
次结构,(b)是一个网格结构。
3.3.3 面向对象的编程( OOP)
军人
军官 士兵
义务兵 志愿兵
交通工具
轮船 客运工具
客轮
汽车
发动机 车身
气缸
(a) (b)
3.3.3 面向对象的编程( OOP)
② 整体 — 部分结构
? 整体 — 部分结构又称作组装结构( composition
structure),它描述对象之间的组成关系,即:
一个(或一些)对象是另一个对象的组成或部
分。客观世界中存在许多这样的现象,例如,
发动机是汽车的一个组成部分。一个整体 — 部
分结构由一组彼此之间存在着这种组成关系的
对象构成,如上右图所示。
3.3.3 面向对象的编程( OOP)
? 整体 — 部分结构有两种实现方式。第一种方式
是用部分对象的类作为一种广义的数据类型来
定义整体对象的一个属性,构成一个嵌套对象。
在这种方式下,一个部分对象只能隶属于唯一
的整体对象,并与它同生同灭。第二种方式是
独立地定义和创建整体对象和部分对象,并在
整体对象中设置一个属性,它的值是部分对象
的对象标识,或者是一个指向部分对象的指针。
在这种方式下,一个部分对象可以属于多个整
体对象,并具有不同的生存期。后一种情况便
于表示比较松散的整体 — 部分关系。
3.3.3 面向对象的编程( OOP)
③ 实例连接
? 实例连接反映对象与对象之间的静态联
系。例如教师和学生之间的任课关系,
单位的公用汽车和驾驶员之间的使用关
系等等。这种双边关系在实现中可以通
过对象(实例)的属性表达出来。所以
这种关系称作实例连接。
3.3.3 面向对象的编程( OOP)
④ 消息连接
? 消息连接描述对象之间的动态联系,即:
若一个对象在执行自己的服务时,需要
(通过消息)请求另一个对象为它完成
某个服务,则说第一个对象与第二个对
象之间存在着消息连接。消息连接是有
向的,从消息发送者指向消息接收者。
3.3.3 面向对象的编程( OOP)
⑺ 多态性 ( polymorphism)
? 对象的多态性是指在一般类中定义的属
性或服务被特殊类继承之后,可以具有
不同的数据类型或表现出不同的行为。
这使得同一个属性或服务名在一般类及
其各个特殊类中具有不同的语义。
3.3.3 面向对象的编程( OOP)
? 如果一种 OOPL(面向对象的编程语言)
能支持对象的多态性,则可为开发者带
来不少方便。
3.3.3 面向对象的编程( OOP)
? 例如,在一般类, 几何图形, 中定义了一个服务, 绘
图,,但并不确定执行时到底画一个什么图形。特殊
类, 椭圆, 和, 多边形, 都继承了,但其功能几何图
形类的绘图服务却不同:一个是画出一个椭圆,一个
是画出一个多边形。进而,在多边形类更下层的一般
类, 矩形, 中绘图服务又可以采用一个比画一般的多
边形更高效和的算法来画一个矩形。这样,当系统的
其余部分请求画出任何一种几何图形时,消息中给出
的服务名同样都是, 绘图, (因而消息的书写方式可
以统一),而椭圆、多边形、矩形等类的对象接收到
这个消息时却各自执行不同的绘图算法。
3.3.3 面向对象的编程( OOP)
⑻ 永久对象 ( persistent object)
? 永久对象是当前 OO领域的一个技术热点。所谓
永久对象,就是生存期可以超越程序的执行时
间而长期存在的对象。
3.3.3 面向对象的编程( OOP)
? 目前大多数商品化的 OOPL是不支持永久对象的。程序
中定义的对象,其生存期都不超过程序的运行时间。
即当程序运行结束时,它所定义的对象也都消失了。
如果一个应用要求把某些对象的属性信息长期保存,
并能在下一次程序运行时加以恢复,就只好借助文件
系统或数据库管理系统来实现。这需要程序员做许多
工作,包括对象与文件(或数据库)之间数据格式的
转换,以及保存与恢复所需的操作。这些工作无疑是
很繁琐的,而且这意味着面向对象的概念的时空范围
只局限于程序运行时间和内存空间,一旦超出这个范
围,对象就变成了传统的外存数据。
3.3.3 面向对象的编程( OOP)
? 永久对象的概念及实现技术可以使上述问题得
到解决。只要程序员声明某个对象是永久的,
则它的存储、恢复、转换等问题一概不用程序
员关心,完全由系统自动解决。呈现在开发人
员面前的是一个, 无缝的, ( seamless)对象
概念。永久对象的意义不仅仅提高了编程效率,
它还使 OOD阶段的数据管理部分的设计大为简
化,而且可实现对象在不同程序之间的动态共
享
3.3.3 面向对象的编程( OOP)
? 永久对象的实现需要有较强的技术支持。它需要一个
能够描述和处理永久对象的编程语言。这种语言的实
现需要基于一个存储和管理永久对象的对象管理系统
( object management system,简称 OMS)。无论是支
持永久对象的 OOPL还是 OMS,其实现都有较大难度,需
要解决对象的存储、恢复、共享、并发存取、一致性
保护等一系列技术问题,所以目前国内外在这方面研
究性的工作较多而实用的产品较少。在我国,由北京
大学等 20多家单位通过, 八五, 科技攻关研制成功的
青鸟 Ⅱ 型系统( JB2)中已经实现了一个 OMS和一个支
持永久对象的 OOPL(叫作 CASE— C++语言),并用它开
发了近 20个软件工具。
3.3.3 面向对象的编程( OOP)
⑼ 主动对象 ( active object)
? 按照通常理解 OO概念,对象是一组属性和一组
服务的封装体。它的每个服务是一个在消息的
驱动下被动执行的操作。
3.3.3 面向对象的编程( OOP)
? 向对象发一个消息,它就响应这个消息
而执行被请求的服务,否则它的服务就
不执行。每个服务相当于过程式语言中
一个过程、函数或例程(在大多数 OOPL
中它的确就是一个等待被调用的过程、
函数或例程。 Smallatlk中称作, 方法,
而没有采用这些传统的术语,但本质上
并没有什么不同)。
3.3.3 面向对象的编程( OOP)
? 所有这样的对象都是被动对象( passive object),
需要通过消息的驱动(或者说通过消息的触发)才能
执行,那么,原始的驱动来自哪里?目前的 OOPL一般
是来自所有类定义之外的一段主程序,例如 C++中的
main函数。以纯 OO风格著称的 Smalltalk,也需要在所
有类定义之外写一段相当于主程序的源码,才能使系
统最终成为一个可运行的程序。这样做是不是纯 OO,
对实践者来说并不重要。特别是,当系统是一个顺序
程序时,做到这一点也没有太大的不便。
3.3.3 面向对象的编程( OOP)
? 在现实世界(问题域)中具有主动行为的事物并不罕
见。例如,交通控制系统中的信号灯,生产控制系统
中异步运行的设备等等。每个具有主动行为的事物在
系统中应该被设计成一个任务,因为它们的行为是主
动的,需要并发地执行。除此之外,在系统设计阶段
还可能因实现的要求而增加其它一些任务。由于任务
是一些主动的、彼此并发的执行单位,所以无法用被
动对象描述。为此,引入了主动对象的概念,在 OOD阶
段进行任务管理部分的设计时用主动对象表示每个任
务。
3.3.3 面向对象的编程( OOP)
其定义是:
主动对象是一组属性和一组服务的封装体, 其
中至少有一个服务不需要接收消息就能主动执
行 ( 称作主动服务 ) 。
? 主动对象的作用是描述问题域中具有主动行为
的事物以及在系统设计时识别的任务,它的主
动服务描述相应的任务所应完成的操作。在系
统实现阶段,主动服务应该被实现为一个能并
发执行的、主动的程序单位,例如进程或线程。
3.3.3 面向对象的编程( OOP)
? 引入主动对象概念解决了系统设计阶段对任务
的描述问题,从而为在实现阶段构造一个描述
多任务的并发程序提供了依据。但是这种依据
只能是编程工作的一个参考,因为目前还没有
商品化的 OOPL能支持主动对象的概念,所以
OOD阶段识别的主动对象无法直接地对应为程
序中的一个主动对象,需要程序员在现有的语
言条件下设法把它实现成一个主动成分。
3.3.3 面向对象的编程( OOP)
? 面向对象的编程语言( OOPL)与已往各种语言的根本
不同是,它的设计出发点就是为了更直接地描述问题
域中客观存在的事物(即对象)以及它们之间的关系,
主要体现在以下几点:
⑴ 客观世界(问题域)是由一些具体的事物构成的。每
个事物具有自己的静态特征(即可以由一组数据表示
的特征)和动态特征(事物的行为或功能,即可以由
一组操作表示的特征)。
OOPL用对象描述问题域中的事物,每个对象由一组属
性和一组服务构成,分别描述事物的静态特征和动态
特征。
3.3.3 面向对象的编程( OOP)
⑵ 客观世界中的事物既具有共同性又具有特殊性。
人类认识客观世界的基本方法之一是对事物进
行分类,即:根据事物的共同性把事物归结为
某些类;考虑一个类中部分事物的特殊可得到
这个类的子类,子类既具有父类的共同性又具
有自己的特殊性。
OOPL用类表示一组具有相同的属性和服务的
对象,并通过继承机制保证子类具有父类的全
部属性和服务。
3.3.3 面向对象的编程( OOP)
⑶ 客观世界中较为复杂的事物往往是由其
它一些比较简单的事物构成的,例如一
架飞机由机舱、机翼和发动机构成。
OOPL中提供了描述这种组成关系的结构
(一般 — 特殊结构、整体 — 部分结构
等)。
3.3.3 面向对象的编程( OOP)
(4) 客观世界中的一个事物可能与其它事物
存在某种行为上的联系。例如:采购员
购入一次货物要引起会计的一次帐目处
理。
OOPL通过消息表示对象之间的动态联系。
3.3.3 面向对象的编程( OOP)
? 由以上几点可以看出,面向对象的编程语言使
程序能够比较直接地反映客观世界的本来面目,
并且使软件开发人员能够运用人类认识事物所
采用的一般思维方法来进行软件开发。面向对
象的语言和人类认识、理解客观世界所使用的
自然语言之间的距离是比较小的。当然,二者
之间仍然存在着一定的距离。自然语言的丰富
多样和借助人脑的联想思想才能辨别的语义,
仍是目前任何一种计算机编程语言无法企及的。
3.3.3 面向对象的编程( OOP)
? 如图 3.7表示随着编程语言由低级向高级的发
展,它们与自然语言之间的鸿沟在逐渐变窄。
开发人员从对问题域产生正确的认识,到用一
种编程语言把这些认识描述出来所付出的劳动
(以及其中可能发生的错误),随着语言鸿沟
的变窄而减少;由机器代替人完成的工作则随
着语言鸿沟的变窄而增多。这正是计算机语言
(以及整个计算机科学)发展的大趋势。
3.3.3 面向对象的编程( OOP)
? 编程语言到计算机之间的深色阴影表示
这部分工作是由机器自动完成的,基本
不需要开发人员花费精力了。自然语言
和编程语言中间的空白区域表示语言的
鸿沟,它表明从人们借助自然语言对问
题域有一个正确认识,到用一种编程语
言正确地表达出来,其间所存在的差距。
而面向对象的语言使这条鸿沟变窄,但
仍有一些距离。
3.4 编程前的准备
? 为了保证开发成果的质量,提高开发效
率,防止错误发生,在实际进行程序编
制之前应作如下方面的准备。
⑴ 制定标准(工作标准和编程基准);
⑵ 知识共享;
⑶ 共享数据准备;
⑷ 综合利用开发环境;
⑸ 注意开发环境与实际应用环境的差异。
3.4.1 确定标准
? 实际编程工作开始前、为了保证开发成果的质
量,系统的开发环境和标准化的工作流程应该
有机地结合起来,把编程作业从头到尾的过程
归纳为标准化的模式,开发者都必须按照这个
标准化模式进行工作,这样可以抑制和防止最
终开发成果因人而异造成的差异,防止错误发
生,提高生产效率,确保程序编制的质量。在
项目开发之前,从事开发工作的管理者必须把
业务工作的次序、流程和最终开发成果的格式
按标准化模式作出开发基准,以取得一致的开
发成果。
3.4.1 确定标准
1、工作标准的制定
? 在准备阶段,所制定的工作标准包含的
内容有:详细设计书的标准、程序设计
的标准以及共有资源利用的规定,如图
3.8所示。
3.4.1 确定标准
? 值得 注意 的是,要根据客户的要求、检
查自己制定的开发标准与客户提出的开
发标准是否一致,决定是选用客户的开
发标准或者采用自己的开发标准。工作
标准的制定和整理是从事工程管理的管
理者的重要任务,程序员必须认识到它
的必要性,严格地按照每一步工作流程
进行开发,细心地遵守每一条开发标准。
3.4.1 确定标准
2、编码标准的制定
? 首先需要明确的是,程序员的创造性发挥,不
在于其个人独特的编码风格和独特的编码技巧,
而应该是统一风格、统一技巧,在减少程序间
品质的差异性、降低程序的出错率、严守工程
工期方面下工夫。同时,制定编码标准还有其
它的重要意义,它可以使全体程序员都遵守同
样的编码标准,排除个别程序员以自己的才能
去理解编码习惯和技巧,增强程序的可读性和
可维护性,使程序质量在一定程度上得到保障。
图 3.9给出制定编码标准的内容。
3.4.2 知识共享的准备
? 使用新技术的开发过程中,为了避免程
序编制技能的不平衡,有必要对开发人
员进行统一培训,因此培训教育计划也
作为项目开发的一部分。项目开始后发
生的各种问题以及问题的解决方法要作
为共通问题通报给各个开发小组,这样
以防止同样的错误再发生。
3.4.2 知识共享的准备
1、事前的人员教育
? 在软件项目开发之前,除了充分利用现有技术
和开发经验外,还须对开发人员进行教育,教
育内容包括两个方面,一个方面是为了适应当
前工作的需要,进行个别的开发案例的技术教
育;另一个方面作为人才的长期培养,需要进
行作为基础能力的技术教育(如图 3.10所示)。
这些培训教育都要作出相应的培训教育计划。
3.4.2 知识共享的准备
2、知识共享
? 所谓共享的知识,在开发环境中有通用的技能
和项目特有的资源两种。 所谓通用技能,是指
本项目开发和在其他项目里使用同一工具进行
开发时的成功经验。把通用技能和有关项目特
有的资源,积蓄在同一个数据库里,最好是由
经验丰富的骨干系统工程师,以知识数据库管
理者的立场,把项目特有的资源抽象化,转换
成通俗易懂的技能积蓄起来,这样便于大家知
识共享和参照,关于知识共享的准备如图 3.11
所示。
3.4.3 共享数据的准备
? 编程工作开始前,必须构筑全部程序员
共享的数据库等资源,集中管理这些共
享资源的场所叫做数据库。数据库里必
须准备的项目是内部设计时作为共享资
源定义的全部项目。如果设计书没有指
出,在编程工作展开时也要列举出必要
的资源并做好相应的准备。
3.4.3 共享数据的准备
? 共享数据准备的内容有:
① 开发测试用的用户登录的帐号。
② 数据库的安装。
·数据库接口定义;
·全领域(数据领域,Log日志领域、索引领域等)
的长度定义;
·作成各领域的物理文件、物理盘分配的定义;
·详细层的数据定义(全索引各 TABLE,COLUMN、
VIEW等);
·建立数据结构之间的关系。
3.4.3 共享数据的准备
③ 通用子程序、类库的封装。
·在现有子程序、类库的功能的调查基础上
确定可利用的通用子程序和类库;
·新建子程序的粒度定义。从功能的观点决
定子程序到哪层为止;是否分割、是否
综合、能否归纳到 1个类库中;
·通用子程序、类库实装
3.4.3 共享数据的准备
④ 出错处理体系化
·出错内容的整理。参照现行系统整理错误内容;
·错误处理的分类;
·异常处理类的设计;
·错误信息标准化(决定错误信息的编号体系、决
定错误信息的分类显示方法、错误信息的格式
定义以及错误信息格式定义的例子);
·错误信息显示处理的实现(把错误信息的显示处
理作成通用的子程序)。
3.4.3 共享数据的准备
⑤ 全局变量、常量
·整理出必要的全局变量、全局常量;
·全局变量、常量的命名。
3.4.4 综合利用开发环境
? 在综合利用开发环境方面,我们可以将
编程过程划分为,Coding(编码 ),
Debug(调试 )两个阶段,
3.4.4 综合利用开发环境
? 关于综合开发环境的功能详见图
3.4.4 综合利用开发环境
⑴ 版本的统一
? 开发组在应用同一综合开发环境的时候,应事先统一
版本,如果版本不完全一致的话,执行模块及动态链
接库工作时就会产生异常。此外,子程序也可能在不
断更新换代,所以,应尽可能利用加载了最新子程序
的测试环境。
⑵ 用户设定的统一
? 尽管多数开发环境都允许用户自由设定显示颜色,嵌
套格式等部分内部参数,但为了严格遵守编程标准,
应事先对 (这些环境的 )用户设定进行统一。实际上,由
于可能有多个程序员使用 1台 PC(开发设备 ),所以最好
事先使开发环境一致,这样才能保证其安全运行。