首页 > 代码库 > 结构化方法与面向对象方法
结构化方法与面向对象方法
结构化方法与面向对象方法
一、引言
谈到结构化方法和面向对象方法,估计在大三之前的我们都会一脸茫然,但经历了大三上的一学期学习,其实这两种方法已经完完全全渗透到了我们方方面面的学习和作业之中,回忆其原因,可能因为我们之前的学习中,不是非常注重站在系统的层面去看待问题,仅仅把目光局限在一个局部要完成的任务上,所以对于这些系统开发的名词感到陌生,这学期先抛开软件工程中学到的不说,单看其他的课程,比如数据库,便是一个系统开发的过程,而我们数据库中用到的开发方法就是典型的结构化方法。在谈到结构化开发方法的过程中,笔者也会全面以我们的数据库开发为例子,来举例说明结构化开发的各种好处。而对于面向对象的方法,虽然在这学期的课程中并没有涉及,但我们软件工程的项目《多级电梯调度系统》其实就是一个建立在面向对象开发方法上的系统,这也是我们在面向对象课上学习的一个重要实例,围绕着电梯的运行,可以将电梯抽象为一个类,对于我们多级电梯,我们只需要在我们设定的类上做进一步的泛化即可。所以其实在谈两种方法之前,我们对这两种方法都已经有了一定的认知,下面我将会对两者从设计与实现,方法与应用,两个方面来谈一谈两者的区别与联系。
二、设计与实现
结构化方法,顾名思义,是一种将系统进行结构化的方法,对于一个整体的系统进行一步一步的细化,拆分成子系统,再从子系统中,分出更多的分支。
结构化方法主要有三个基本思想:自顶向下、模块化以及语句结构化。[1]
以我的理解,结构的设计和分析是自顶向下的分析,而实现起来,是一种自底向上的递归实现过程——设计过程中,我们通览全局,从顶端的大系统开始,细化我们的设计,到每一个小模块,实现的时候,从一个个子模块子系统开始实现,最后统合成我们整个的系统架构。
以数据库设计为例:数据库的课程设计便是开始于系统设计报告,在这份报告中,我们将从最顶层开始设计整个数据库,依据用户的功能和需求,将系统进行分层,细化实体。
例如我们的数据库数据流图如下,这便是一种自顶向下的结构化方法,当然这只是0层数据流图,之后,我们会对于每一个小模块进行1级数据流图的分析,将一个难以入手实现的大系统,最后拆解成了一个一个层次化的小模块。
图1 以数据库课程设计0层数据流图为例的示意
在我们实现的过程中,只需要对照每一个数据流图的子模块,设计对应的数据表项,完成对应的功能以及数据流关系,便能规约汇总,自底向上,最后获得整个系统。
图2 以多级电梯调度为例的结构化方法示意
而面向对象方法,源自对现实世界的一种抽象,他是一种更接近于人类思考模式的方法,不同于系统化的设计实现模式,他注重的是整个系统被分解成对象的集合,而不是功能的集合,每个对象有自己的职责,对象之间相互协作来完成用户交给的任务。
面向对象方法的三个思想:封装,继承,多态边很好阐释了面向对象方法的核心原理。[2]
在设计与实现上,面向对象的方法可以概括成,设计对象并实现对象。面向对象方法关注的是参与到系统中的对象集合。每个对象之间都可以独立存在,在一个整体中组成一个系统,所以对象之间没有结构化方法模块之间的父子关系,强依赖关系,也不用像结构化设计一样,自顶向下的有序设计。
比如电梯系统,我们的关注点从如何实现一个可以控制电梯的系统,到了如何实现一个对于电梯的抽象,当你抽象好电梯之后,你就相当于造好了一部电梯,这个时候,你就可以将它衍生成为很多部电梯,在系统的不同需求下满足不同的要求进行使用,这也就是所谓的封继承和多态的基本体现。不同于结构化设计方法,我们关注的并不是电梯的系统的每个功能应该怎么实现:如何电梯开门,关门,控制上升下降,当然这些东西最后在系统中我们也会实现,但我们的基本目标,是做出一部电梯。而上升和下降,只不过是你交给电梯的一个任务而已。设计的关注点不同了,实现的要点也有所区别,就如结构化方法的实现是子模块的聚合规约一样,面向对象的实现要点是对象以及其之间的相互关系构建。
面向对象方法UML图中的usecase实例与类图实例,与上面结构化方法中的设计实现形成了很大的对比,图中对于实现方法的关注点不在局限于层次和功能,而是对象的完整程度和使用对象的方法之上。
图3 电梯模块类图
图4 电梯系统用例图
三、方法与应用:
从抽象的系统层面下降下来,我们虽然谈了很多关于结构化方法和面向对象方法的特点与思想,但究竟什么才是结构化方法,什么才是面向对象方法?他们的目前的应用情景又有哪些?这些或许才是我们更关心的。
3.1 解决方法:
结构化方法,也是一种面向过程编程的体现,程序代码上以一个个function聚合来解决实际问题,在这种类型的程序中,程序员总是能对一个实际的问题给予他最直接的解决。这种直来直往的代码风格带来的就是高效的代码处理能力:我们无需关注整个问题的模型架构,我们只需要关注问题的核心和问题的解决方法。结构化的程序,更像是我们做的解决应用题,其中的每一步公式都是直逼问题的解决。[3]
比如一个应用题,去市场买东西,给出了我们购物清单,让我们求所需要花费的钱。
在这个问题中,结构化的方法关注的子问题是每一个水果对应的单价即购物清单上的数量,聚合成的系统便是所有这些水果价格的总和。我们所需要做的仅仅是根据清单,找到对应物品的单价,进行计算,最后将所有的计算结果进行求和即可。
图5 结构化方法描述买水果问题
显然,这种程序是一种完全由程序员所掌控的程序,拿到特定的工程任务之后,程序员可以用它的代码和程序最快的解决任务,你需要提供给外界的就是一个输入和输出的窗口,剩下的结构都是由一个黑箱(black box)所概括,无需多余的用户交互。
而面向对象方法,是一种面向对象编程的体现。代码中会抽象出很多类,我们在实现我们的程序的时候,是运用我们设计的类进行实现的。可以这么理解一个面向对象的解题过程,同样是出了一个应用题,而我们去做的并不是直接去列公式解决应用题,而是构建一个关于这个问题的模型,从模型出发去泛化到我们这个应用的问题再去进行解决,因为其设计的功能有冗余的情况,所以其代码效率肯定不如结构化方法来的高效直接。但这种风格是用户友好的,掌控整个问题架构的不再是程序员一个人,程序员给出的是一种通用模型化的解决方法,这种方法中,程序员提供的不再是一种解决方法,而是若干个通往解决方法的工具。[3]
再用上面例子中的应用题做一个例子。
在使用面向对象的方法中,程序中所包含的往往就不是这么一个价格求和公式了,程序会 从水果这个类为原点开始出发,即把一个购买水果问题抽象称为用户对水果这个类的一个购买动作。从水果中可以实现对不同水果包括橘子,香蕉,苹果的不同定义,这之间我们所关注的是他们各自单价的不同,用户的购买清单作用的是这一个个对象,整个程序的实现过程更接近真实买水果的过程:摆在用户面前的对象就像是一个个水果一样,用户做的只是挑出想要的,价格标签自然在上面都有。
图6 面向对象方法描述水果问题
3.2应用场景
应用从它们各自的解决问题的途径出发,我们可以体会他们各自应用场景的不同。
对于结构化方法,更适合存在于各类科学计算,分析的程序之中——这些问题往往都是黑箱类问题,我们所关注的往往只是他的输入输出,当然最重要的还有运行效率。这恰好符合了结构化编程的主要特点。当计算一个流体力学方程的时候,当然你会想的是各个力学方程的构建与求解,有限元分析的流行划分,而不会去想将一个流体抽象成一个类,描述流体的性质去解决这个问题。在主流的科学计算语言和工具如:FORTRAN,MATLAB中,这种结构化编程的思想仍是构建他们的核心。
当然这也与发展历史有很大的关系,计算机程序,在早期的使用中,更多的就是作为一种解决人难以解决的计算问题的工具而广为流行和发展的,随着计算机在社会地位上的提高,交互这个概念才越来越获得大家的重视,面向对象的方法才跃居主流。[4]
面向对象方法在现在各类的用户交互软件中使用的尤为频繁,程序员无法准确的预测到用户所有的行为组合,从而系统无法很快且有限的规约到子问题中进行解决,即便可以解决,所需要的代码量和复杂度也非常之大。相反而言,面向对象方法以其得天独厚的优点,可以不关注具体的功能集合而将目光投在对象之上,这正吻合了用户操作程序的思维,在这种方法中,用户的行为就能很容易的被有限归纳到对给出对象的指定操作之中,从而很好的解决这类问题。比如游戏等需要大量交互的程序中,面向对象的方法广为存在。
四、总结
无论是结构化方法还是面向对象方法,都有着其独特的特点,不能以“面向对象后来居上,成为当今主流”这一论调来否定结构化方法在特定领域的强大作用,也不能以效率至上论来否定面向对象的强大兼容性。在我们拿到一个系统的时候,只有充分理解和掌握了面向对象和结构化方法的特点和特征的时候,我们才可以将两种方法融汇贯通,使用得心应手。
参考文献:
[1]百度百科——结构化方法 baike.baidu.com/结构化方法
[2]百度百科——面向对象方法 baike.baidu.com/面向对象方法
[3]结构化方法与面向对象方法的比较分析 张莉,裘国永 《陕西师范大学学报(自科版)》, 2001, 29(2):29-32
[4]结构化方法与面向对象方法之区别 http://blog.sina.com.cn/s/blog_59a104d20100a79o.html
结构化方法与面向对象方法