结构化方法与面向对象方法之比较

  这篇文章也是原来上软件工程课的时候的调研作业,原博客在这里

引言

  所谓软件开发方法,就是为了满足在有限的项目投资、开发时间内,尽可能地设计、实现出符合用户要求且高质量的软件而提出的开发策略,根据这些策略将整个软件开发过程变得更加科学化、系统化。当然,在软件开发领域存在各种各样的系统分析和设计方法,但其中结构化方法与面向对象方法是软件开发程序设计中的两个核心思想。

  结构化方法起源于20世纪60年代对于GOTO语句的争论和认识,经过几十年的研究及应用,最为成熟且影响最大,而面向对象方法近10年来发展较快,被广泛应用于计算机软件的各个领域。

  结构化方法的核心思想是自顶向下(逐步求精)和模块化设计(结构化编码),从原问题出发不断拆分、不断简化,最终将问题划分成相对独立的多个小问题,之后再以模块化的形式进行编程;而面向对象方法则以对象为中心,将问题中涉及到的各项事务抽象分解为多个对象,问题便存在于对象之间的交互、关联中,藉由对象的行为进行表现。

结构化方法

概述

  结构化方法(SD方法)是一种成熟、传统的软件开发方法。它的组成部分有结构化分析(SA)、结构化设计(SD)和结构化程序设计(SP),分别对应软件生命周期的分析、设计和编码阶段。基本思想为把一个复杂问题的求解过程分阶段进行,而且这种分解是自顶向下,逐层分解,使得每个阶段处理的问题都控制在人们容易理解和处理的范围内。

  这里借用一张经典的图来表示自顶向下分解的过程:

结构化分析

  结构化分析的基本思想是“分解”和“抽象”,并最终用数据流图、 数据字典、 判定表、判定树等图形来对分解、抽象的结果加以表达。下面介绍其中最为的三种——数据流图、数据字典和结构图。

数据流图(DFD)

  数据流图(Data Flow Diagram,简称DFD)是一种常见的描述系统中数据流程的图形工具,以图形方式来表达系统的逻辑功能、数据在系统内部的逻辑流向和逻辑变换过程。

  数据流程图中有以下几种主要元素:

  →:数据流。数据流是数据在系统内传播的路径,因此由一组成分固定的数据组成。如订票单由旅客姓名、年龄、单位、身份证号、日期、目的地等数据项组成。由于数据流是流动中的数据,所以必须有流向,除了与数据存储之间的数据流不用命名外,数据流应该用名词或名词短语命名。

  □:数据源(终点)。代表系统之外的实体,可以是人、物或其他软件系统。

  ○:对数据的加工(处理)。加工是对数据进行处理的单元,它接收一定的数据输入,对其进行处理,并产生输出。

  〓:数据存储。表示信息的静态存储,可以代表文件、文件的一部分、数据库的元素等。

  同时出于结构化、模块化的要求,数据流图也应该以分层的形式来绘制。其绘制方法为:1、确定系统的输入输出;2、由外向里画系统的顶层数据流图;3、自顶向下逐层分解,绘出分层数据流图。

  下图是一张典型的数据流图的示例:

数据字典(DD)

  数据字典(Data Dictionary,简称DD)是指对数据的数据项、数据结构、数据流、数据存储、处理逻辑、外部实体等进行定义和描述,其目的是对数据流程图中的各个元素做出详细的说明。

  上述分层数据流图只是表达了系统的“分解”,为了完整地描述这个系统,还需借助数据词典对图中的每个数据和加工给出解释。

  通过这几种表述工具,我们可以将分析步骤归纳如下:

  ①分析当前的情况,做出反映当前物理模型的数据流图(DFD);

  ②推导出等价的逻辑模型的数据流图(DFD);

  ③设计新的逻辑系统,生成 数据字典和基元描述;

  ④建立人机接口,提出可供选择的目标系统物理模型的DFD;

  ⑤确定各种方案的成本和风险等级,据此对各种方案进行分析;

  ⑥选择一种方案;

  ⑦建立完整的需求规约。

结构化设计

  结构化分析完成了软件开发周期中的(需求)分析部分,知道了在软件开发阶段应该做些什么。接着就应该是结构化设计(SD)来对整个软件项目进行设计,描述整个系统的设计思路和框架,了解如何进行软件的开发。

  结构化设计的重要目的就是将软件项目模块化,因而我们有必要先介绍一下模块结构图。

结构图(SC)

  结构图是一个将系统拆解为最小可管理程序单位的图。在结构化设计中,结构图可以将程序模块整理为树状结构,每一个模块以一个其中有模块名称的方框表示,树状结构可以清楚表示各模块之间的关系。

  结构化分析中常用结构图表示程序的顶层架构。结构图有助于程序设计者用个个击破的方式处理软件问题,也就是将一直将问题拆解为更小的问题,直到最后问题小到可以被人类理解为止。此程序称为由上到下设计或是功能分解。结构图的作用类似建筑房屋中使用的蓝图。在设计阶段,结构图是客户和不同软件工程师沟通的方式。在代码实现的阶段,由结构图可以得知系统的完整架构。

  结构化设计的基本思想就是根据结构化分析方法得到的数据流图(DFD)建立结构图(SC),从而达到尽可能用程序结构反映需要解决问题的结构的目的。当然,此时得到的结构图还只是初步的结构图,还需要根据结构化设计的基本原则和有关启发规则,对结构图进行进一步的优化。

结构化程序设计

  结构化程序设计(structured programming,简称SP)由结构化设计得到的结构图划分功能模块,自顶向下分解任务,并将其分配相应的开发人员,开发过程中一般要求仅利用顺序、选择、循环三种基本结构。通过这样的方式,开发人员不需要考虑软件项目的总体,而仅仅需要分析自己开发的部分,这样有利于对单元模块进行详细的测试,也能很好地保证软件的开发质量。

面向对象方法

  面向对象的出发点是尽可能模拟人类的思维方式,将软件开发过程变得更加接近人类认识世界、解决问题的过程。为了达到这一点,面向对象方法通过引入对象、类、封装、继承、多态等概念来支撑其开发方法,打破了传统的代码、数据分离做法,而是将一种数据结构和操作该数据结构的方法捆在一起, 封装在一个程序内,实现了数据封装和信息隐藏,通过“ 操作”作为接口实现信息传递。对外部来说,只知道“ 它是做什么的”,而不知道“ 它是如何做的”,使得数据封装、 信息隐藏、 抽象代码共享等软件工程思想得到充分体现。

  面向对象方法(Object-Oriented)包括面向对象分析(OOA)、面向对象设计(OOD)和面向对象程序设计(OOP)三个部分。

面向对象分析(OOA)

  面向对象分析时面向对象方法的第一个环节,这一环节的任务是将问题和对项目的理解,抽象成规范的对象和消息传递,从而建立起整个面向对象软件开发的基础。一般这一部分对于新手来说是较难的,因为要适应相应思维的转变。上个学期OO课程的开头部分,大家应该能够感受到,很难正确地对问题中的对象进行准确划分,但是在适应这类思维方式之后,在处理其他问题时很能很容易对问题进行抽象。

  总的来说,OOA建立在封装、抽象、多态这三个概念之上。

 封装

  面向对象方法中,通过封装机制将数据和相应的操作捆绑到了一起,以形成一个完整的、具有属性(数据)和行为(操作)的数据类型。这就实现了从数据和操作两个方面来描述某个事物,更加符合人们描述某个事物的思维习惯,因此也更加容易理解和实现。

 继承

  继承可以让某个类型获得另一个类型的属性(成员变量)和行为(成员函数)的简单方法。继承就如同现实世界中的进化一样,继承得到的子类型,既可以拥有父类型的属性和行为,又可以新增加子类型所特有的属性和行为。这样大大提高了开发的效率,这是传统面向过程开发所难以实现的。

 多态

  多态是继承的直接结果。但是虽然继承了父类型的属性和行为,不同的对象间有着差异,有不同的操作,所以面向对象方法通过给出接口调用不同类的“同一行为”实现了对象的多态。

  有了上述的三者,OOA则通过五个层次(主题层、对象层、结构层、属性层和服务层)上的抽象,完成对问题的完整分析,最终得到问题的抽象结构。

面向对象设计(OOD)

  OOA 和 OOD 采用一致的概念、 原则和表示方法,二者之间不存在鸿沟,不像上面所述的结构化方法,从OOA到OOD不需要从分析文档到设计文档的转换。它们之间没有明显的边界,甚至可能有一定程度的交集。

  其中两者的区别主要是:OOA 与系统的问题域更加相关,OOD 与系统的实现更加密切;OOD 是对 OOA 所得出的对象模型的直接细化和抽象,得到可直接实现的类图。

  通过OOA的初步分析我们得到了:问题 = 对象 + 类 + 继承 + 消息传递,而OOD则进一步过渡,对OOA分析的结果作进一步的规范化整理,以便能够被OOP直接接受。

面向对象程序设计(OOP)

  OOP是近几年来最为流行的开发方式之一,并且在实际应用中展现了巨大的威力。

  OOP 达到了软件工程的三个主要目标:重用性、灵活性和扩展性。通过接口的设计,实现了整体运算,每个对象都能够接收信息、处理数据和向其它对象发送信息。OOP 主要有以下主要的概念:

  组件:数据和功能一起在运行着的计算机程序中形成的单元,组件在 OOP 计算机程序中是模块和结构化的基础。

  抽象:程序有能力忽略正在处理中信息的某些方面,即对信息主要方面关注的能力。

  封装:确保组件不会以不可预期的方式改变其它组件的内部状态;只有在那些提供了内部状态改变方法的组件中,才可以访问其内部状态。每类组件都提供了一个与其它组件联系的接口,并规定了其它组件进行调用的方法。

  多态:组件的引用和类集会涉及到其它许多不同类型的组件,而且引用组件所产生的结果得依据实际调用的类型。

  继承:允许在现存的组件基础上创建子类组件,这统一并增强了多态性和封装性。典型地来说就是用类来对组件进行分组,而且还可以定义新类为现存的类的扩展,这样就可以将类组织成树形或网状结构,这体现了动作的通用性。

  以上的四个概念侧重于系统实现的角度,和OOA段的概念阐述并不完全一致。

面向对象方法和结构化方法的比较

  首先,面向对象方法较之与传统的结构化方法有其独到之处:

  1) 可重用性。可重用性是面向对象软件开发的一个核心思路。通过类的继承关系,使公共的特性能够共享,简化了对象、类的创建工作量,增加了代码的可重性。另外,重用经过测试的代码还可以使产生额外错误的可能性达到最小。

  2) 可扩展性。可扩展性是对现代应用软件提出的又一个重要要求。类的继承性使类能反映现实世界的层次结构,多态性反映了现实世界的复杂多样。类的继承性和多态性使软件编码具有良好的可重用性和可扩展性。无需修改源代码就可以使软件功能容易扩充和修改。

  3) 数据保护。数据和操作数据的算法不再分离,它们被封装在一起,对象内部的行为实现细节被隐藏。封装防止了程序相互依赖性而带来的变动影响。

  4) 可管理性。面向对象的开发方法采用类作为构建系统的部件,以对象作为系统的基本组成单元,使整个项目的组织更加合理、方便,因为归纳事物、 划分类进行管理符合人们在认识和管理客观世界的习惯思维方式。

  然而面向对象方法和结构化方法相比也存在一些弊端:

  1) 上手慢。新手在接触到面向对象方法时,往往很难准确的将问题分解为多个类之间的联系。而且即使经过一段时间的训练,对于一些比较复杂的问题也很难做到通过类和类之间的信息传递来准确描述。

  2) 认识差异。对于一个相同的问题,很难有一个确定性的划分,所以就会出现不同的设计人员对于类、类之间的联系的理解不一致,而这种不一致很难通过统一的方式表达出来,这就可能会导致后期面向对象程序设计OOP过程中出现分歧。

  3) 编程便捷性。在编写程序方面,结构化方法有着比较强的优势,它思路清晰,条理严谨,步骤整洁,便于阅读理解。这一点也正是很多企业开发项目时首先通过面向对象方法进行分析设计,之后通过模块化、结构化的方式进行软件开发的原因。

总结

  程序设计方法的发展经历了四代,而经过几十年的更迭,结构化方法和面向对象方法成为当代软件工程的程序设计方法中最本质的两种思想方法,足以体现优越性。

  结构化方法体现了抽象思维和复杂问题求解的基本原则,面向对象则深刻反映了客观世界由对象组成这一本质特点。各种程序设计方法的一个重要区别在于问题分解的出发点不同(因子),思维模式不同。计算机中数据结构和过程是密切相关的,结构化方法将数据结构和过程分开考虑,面向对象的方法组合数据和过程于对象之中。理论上,对象式方法将产生更好的模块内聚和耦合特性,使得软件更易于重用与维护,但在实践中程序设计方法需要工具和环境的支撑,需要考虑软件生命周期的各个环节,在选择程序设计方法时,需要综合考虑这些因素,适当选用其中一种或者是综合使用。

  最后借用一句俏皮话来描述两者之间的差别:结构化方法是编年体;面向对象方法是纪传体。

参考资料:

[1] Wikipedia,结构化方法、面向对象方法

[2] Baidu Baike,结构化方法、面向对象方法

[3] 符于江. 程序设计中结构化方法和面向对象方法的比较[A]. 海南: 电脑知识与技术,2008

[4] 汪寒昊. 软件开发方法_结构化方法与面向对象方法比较[A]. 四川: 科技信息,2011

本文遵守 CC-BY-NC-4.0 许可协议。

Creative Commons License

欢迎转载,转载需注明出处,且禁止用于商业目的。

上篇虚拟机、WAMP/LAMP安装
下篇全局变量、局部变量、静态全局变量、静态局部变量的区别