关于面向对象与面向过程(面向结构)的区分

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

 

最近又有客户问起结构化方法(即结构化分析SA Structured Analysis 和结构化设计SD Structured Design)和面向对象分析设计(OOAD Object-Oriented Analysis & Design)方法的区别,这是一个很多人谈了很多遍的问题,Google一下就可以找到很多以此为标题的文章。OO技术发展了很多年了,现在大家都在用,已经没有什么异议了,几乎没有人会怀疑这种技术的好处。但它明显是一位过气的明星,就连前几年才出道的模型驱动开发(MDD)也已经过了风头最劲的时段,我们现在更热衷于讨论一些更加时尚的概念如:SOA、IT治理、循规等。

   要想了解结构化方法和面向对象方法,去看一下 Roger S.Pressman 写的"软件工程:实践者的研究方法(Software Engineering: A Practitioner's Approach)"(这是一本很流行的书,网上就有卖)就可以了,里面有专门的章节介绍这两种方法及其区别。

    我喜欢把软件系统描述成对现实世界的映射,现实世界中的我去ATM机取了100元钱,映射到软件就是从我的银行帐户对应的数据库记录中余额(Balance)那一字段减去100。所谓的结构化方法和面向对象方法,就是两种不同的映射手段,结构化方法是以处理过程为中心,强调先定义数据结构(ER实体关系建模),然后分析处理逻辑(DFD数据流图);面向对象方法则主张两者之间的自然映射,在ATM取款的例子中,我被映射为Customer对象,我的帐户被映射为Account对象(在对象-关系映射中再对应到数据库表Account中的一条数据记录)。正因为OO方法采用对现实世界的自然映射,现实世界中的业务流程发生变化时,软件实现也可以比较方便地跟着转变;而采用结构化方法的映射(或是采用OO方法,但对业务流程的映射关系建立不当),软件上相应修改的工作量就会大一些。

    应当说明的是这两种开发方法之间并不是一个完全对立的关系,结构化方法出现在前,并且得到了很成功的应用;面向对象方法诞生在后,说它是从结构化方法发展而来也不为过,它也继承了很多结构化方法中的成功经验如:数据抽象、自顶向下、模块化、高内聚、低耦合等,我们应该把OO技术看作是软件设计方法的最佳实践经验整合。结构化方法在过去也很成功,但是我们所开发的软件规模越来越宠大,软件系统越来越复杂,20年以前开发一个软件可能是100%从头开发的,现在开发一个软件可能只有10~20%的代码是新开发的,很多功能尤其是基础功能都是可以重用的。J2EE技术就是一个典型的例子,它把很多基础功能如会话(Session)管理、事务(Transaction)管理、对象关系映射(O-R Mapping)等都已经在中间件中实现了,你只需要重用它们就可以了。要提高软件重用性的话,就一定要引入OO方法中的一些关键理念如:封装、多态、抽象层次结构等,这些机制可以提高软件的可重用度,帮助我们有效地管理软件系统日益增长的复杂度。

    实际上结构化方法和面向对象方法之间并不是革命性的变化,我把它们比喻为“走路”和“跑步”的区别,原始人为了捕捉猎物,必须跑步前进;跑步跟走路的区别不是很大,仅仅是迈步频率加快,并且双脚可能同时离地而已。而模型驱动开发(MDD)则是一种革命性的变化,我把它比喻成“骑自行车”,因为MDD已经开始利用自动化工具来提高软件开发生产率了,但是MDD技术还刚刚处于探索阶段,还没有成为一项大规模应用的成熟技术。对应于这种比喻的话,我们可以看到软件开发技术发展是非常缓慢的,相比其他行业(如集成电路)的技术发展,软件开发技术还很落后。我们大部分人还在使用原始的开发手段,等到将来我们把软件开发技术发展到“开汽车”、“坐飞机”的阶段,可能我们就找到了软件工程的“银弹”。那个时候可能我们只需要把需求告诉电脑就行了,它就会自动地做到我们想要的东西。
                走路     跑步      骑自行车    开汽车、坐飞机
                结构化方法  面向对象方法  模型驱动开发  将来的软件开发技术 

    我观察到在实际应用中使用什么样的设计方法往往受制于编程技术和环境,采用COBOL(主机应用开发)、C等传统过程语言的开发人员一般都在使用结构化方法进行设计;而采用Java、C++等面向对象语言的开发人员受到对象概念的熏陶比较多,基本上会转向面向对象方法;当然也有例外,也有一些开发人员在用C++语言实现面向过程的设计,因为他们还没有领悟OO所带来的好处。如果你想从结构化方法转向OOAD方法的话,我建议你先从OOP(Object-Oriented Programming)开始,使用Java、C++这些经典的OO编程语言可以让你逐步掌握OO技术的妙处,这样再转向OO设计就会容易一些,这是自底向上的实践。

********************************************************************************

 

 

 

 

面向对象和面向过程区别的很好地范例

 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。 

面向对象是把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

例如五子棋,面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用分别的函数来实现,问题就解决了。

而面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为 1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的i变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了总多步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。

功能上的统一保证了面向对象设计的可扩展性。比如我要加入悔棋的功能,如果要改动面向过程的设计,那么从输入到判断到显示这一连串的步骤都要改动,甚至步骤之间的循序都要进行大规模调整。如果是面向对象的话,只用改动棋盘对象就行了,棋盘系统保存了黑白双方的棋谱,简单回溯就可以了,而显示和规则判断则不用顾及,同时整个对对象功能的调用顺序都没有变化,改动只是局部的。

再比如我要把这个五子棋游戏改为围棋游戏,如果你是面向过程设计,那么五子棋的规则就分布在了你的程序的每一个角落,要改动还不如重写。但是如果你当初就是面向对象的设计,那么你只用改动规则对象就可以了,五子棋和围棋的区别不就是规则吗?(当然棋盘大小好像也不一样,但是你会觉得这是一个难题吗?直接在棋盘对象中进行一番小改动就可以了。)而下棋的大致步骤从面向对象的角度来看没有任何变化。

当然,要达到改动只是局部的需要设计的人有足够的经验,使用对象不能保证你的程序就是面向对象,初学者或者很蹩脚的程序员很可能以面向对象之虚而行面向过程之实,这样设计出来的所谓面向对象的程序很难有良好的可移植性和可扩展性。

 

 

*********************************************************************************************

面向对象跟结构化的区别与分析

按我的理解,所谓的面向对象就是就是在程序设计中按类来对系统进行设计。举个例子,要发广告邮件,广告邮件列表存在数据库里面。倘若用C来写的话,一般会这样思考,先把邮件内容读入,然后连接数据库,循环取邮件地址,调用本机的qmail的sendmail命令发送。
  然后考虑用Java来实现,既然是OOP,就不能什么代码都塞到main过程里面,于是就设计了三个类:
    一个类是负责读取数据库,取邮件地址,调用qmail的sendmail命令发送;

  一个类是读邮件内容,MIME编码成HTML格式的,再加上邮件头;

  一个主类负责从命令读参数,处理命令行参数,调用发email的类。

仔细的分析一下,就会发现这样的设计完全是从程序员实现程序功能的角度来设计的,或者说,设计类的时候,是自低向上的,从机器的角度到现实世界的角度来分析问题的。因此在设计的时候,就已经把程序编程实现的细节都考虑进去了,企图从底层实现程序这样的出发点来达到满足现实世界的软件需求的目标。类与类之间是通过发送和接收消息相联系的,接收消息的对象通过调用类的方法来实现相应的操作。访问限制符Private、protected和public将类分成三个部分:私有部分、保护部分和公有部分。使数据具有不同的隐蔽程度。类定义可包含一组构造函数和析构函数,构造函数保证了在声明类的对象时对其自动初始化,而析构函数则保证对类的对象正常地清除。从已有的类还可以派生瓣的类,前者称为基类,后者称为派生类,OO方法中继承的原则在这里得以体现。能够突破类的私有部分,禁止其它函数直接访问限制的友员机制,以及由运算符重载、函数名重载和虚函数构成的多形性,使程序员能以更自然、方便的表达方式实现对象的操作。

    当然万事万物皆为对象,而对象又是类的实例,因此在面向对象的编程中,就如上面的例子,我们可以在分析三个大类的前提下,定义这些类的对象。大家都知道任何对象都会有

属性,方法,过程,函数,事件等,且类与类之间又可以继承,子类继承父类,子类间有多态性。类也可以先进行封装,再使用。这些都是面向的特性,当然它还有一个代码可重复使用的特性。也是因为如此,在程序设计中如果采用面向对象的编程方式可以更好的以人类的正常思维进行分析。至于具体的分析,到后面将用俄罗斯方块来分析。相比之下,传统的结构化程序设计则采用另外一种编程方式,它是采用按模块功能进行系统分析的,下面附出结构化方法的大概流程图。图略
 

结构化程序设计的主要思想是功能分解并逐步求精,当一些任务十分复杂以至无法描述时,可以将它拆分为一系列较小的功能部件,直到这些自完备的子任务小到易于理解的程度。例如,计算一个公司中每一个职员的平均工资是一项较为复杂的任务。可以将其拆分为以下的子任务

(1)       找出一个人的收入

(2)       计算总共有多少职员

(3)       计算工资总额

(4)       用职员人数去除工资总额

而计算工资总额本身又可以分为一系列子任务:

(1)       找出每个职员的档案

(2)       读出工资数额

(3)       把工资加到部分和上

(4)       读出下个职员的档案

类似地,读出每个职员档案的记录又可以分解为一系列子任务

(1)       打开职员的档案

(2)       找出正确记录

(3)       从磁盘读取数据

具体看来结构化程序具有以下几个特征:自顶向下,逐步细化,模块化设计,结构化编码

从软件工程发展的历史来看,早期的软件开发量小,结构化程序设计在成功地为处理复杂问题提供了有力的手段。然而到80年代末,它的一些缺点越来越大。比如当数据量增大时,数据与处理这些数据的方法之间的分离使程序变得越来越难以理解。对数据处理能力的需求越强,这种分离所造成的负面影响越显著。并且对于每一种老问题的新方法都要带来额外的开销,与可重用性相比,这种编程思想显得落后许多。面向对象就是在这种情况产生了,相信在未来十年内,面向对象还将继续发展。

    介绍完了两者大致的定义后,接下来用俄罗斯方块来分析一下两种编程思想具体的不同

对于结构化程序的方法,在这里用脚本语言javascript来描述,而面向对象则采用如日中天的java来分析。

首先按结构化编程方式来完成俄罗斯方块的话,我们会对问题按数据结构进行模块化的分解,本程序将用以下几个模块来完成:

(1)       开始游戏(function beginGame())

(2)       俄罗斯方向键的控制(function keyControl())

(3)       块的消除(function decline())

(4)       面板的移动(function moveBar())

(5)       暂停游戏(function pauseGame())

(6)       游戏重新开始(function replayGame())

(7)       方块的显示(function randBar())

在分解这几个模块后,就已经大致完成了对程序的整体分析了。这是对程序中问题的描述,接下来则是具体的算法分析,也是结构化当中的解决问题了。要解决本程序中最主要的一个算法一一方块的显示算法,在本程序中采用四维数组的方式来表达方块,比如:

1,0,0,0

1,0,0,0

1,0,0,0

1,1,1,1

这样则表示方块中的L形状态,其他则不在一一列出。其他算法的则略过。还是把重点转移到面向对象中来。

在面向对象中首要解决的是本程序中要分为几大类来完成最基本的系统设计。这个俄罗斯方块放在网页中,也就是采用applet小程序的形式,但由于java跨平台性,它可以在windows,linux,unix等操作系统中使用。本程序大致分为三个大类:Tetrisapplet,Brick3D,Board。下面是TerisApplet的UML图:                                 
 

                                      TerisApplet

                                  Init()

                                  Initcomponent()

                                  Minewgameactionperformed()

                                  Miendgameactionperformed()

 



(1)       init():初始化applet

(2)       initcomponent():初始化窗口以及窗口中的组件

(3)       minewGameActionPerformed():当选择菜单或者工具栏上的“开始游戏”命令后,开始新游戏。

(4)       miEndGameActionPerformed():当选择或者工具栏上上的“结束游戏”命令后,结束游戏。

2.Brick3D
Brick3D定义主要有reset(),getShapeIno(),getAngle(),getShape(),rotate()和paint()方法。其中getshapeInfo(),getAngle(),getShape()用于获取砖块的形状信息,矩阵、角度和形状值。Totate()方法用于旋转砖块,paint()方法用于在指定的地点给制砖块
  
 

3.Board

Board类实现俄罗斯方块的主要大部分功能,下面是它的UML图

 略


 

从建模图中可以看出:Board实现的方法有drop()、move()、reset()、newGame()、endGame()、run()、paint()、createNewBrick()、checkRow()、processKeyEvent()、processMouseEvent()、processMouseWheelEvent()等方法,这些方法的功能定义如下。

(1)       drop():砖块的下落函数。

(2)       move():移动砖块,1表示向右移动,-1表示向左移动

(3)       reset():初始化board_info数组

(4)       newGame():开始执行线程(游戏)

(5)       endgame():停止执行线程(游戏)

(6)       run():线程运行的函数

(7)       paint():绘制背景,边界和砖块

(8)       createNewBrick():创建下一个新的砖块形状、角度和颜色,角度、形状和颜色随机产生

(9)       checkrow():检查是否可以消行,并计算分数

(10)   processKeyEvent():处理键盘事件,控制砖块的移动和旋转

(11)   processMouseEvent():处理鼠标事件,控制旋转和左右移动

(12)   processMouseWheelEvent():处理鼠标滚轮事件,当向下滚动时,控制块向下移动

分析完后,本程序用了三个主要的类:Brick3D对象、Board对象和TerisApplet对象,分别对应Brick3D.java,Board.java和TetrisApplet.java三个文件,在实例中还包括了一个Html文件。

  虽然用面向对象写的代码更多,看似面向对象更为麻烦,但实际上面向对象更能解决现在的软件工程问题,而结构化程序设计的方法只对小型的软件设计适合。未来十年内面向对象还是软件开发的主流。 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Java面向对象程序设计实验课的心得体会 经过这几周对Java面向对象程序设计的学习,让我更加了解到Java学习的重要性。 在实验课上,我们完成多个实验,在这个阶段的学习中,我从认识到熟悉,而后到 能够自主运用。通过对Java的了解,我发现它确实有很多方便之处,它集抽象性、封装 性、继承性和多态性于一体,实现了代码重用和代码扩充,提高了软件开发的效率。对 于我们这个专业来说学好Java语言是很重要的,所以在实验的过程中我都尽力理解java 编程思想、掌握基本技巧,尽量学到最多的知识。 学习程序设计的基本目的就是培养描述实际问题的程序化解决方案的关键技能,Ja va面向对象程序设计是一门实践性比较强的课程,在实际中,我们必须把理论和实践结 合起来。在实验中,我们理解理论课上的知识,然后运用到实际的操作中,我们必须在 现有的理论的基础上,进行实践。多次实验后,也让我看到了现在学习的一个很大弱点 :只听不练,永远不会熟练运用;空记技巧,忽略思想,会在多变的习题中十分无奈。 Java思想:Java是一门面向对向语言,他定义一切都是对象 面向对象,就是面对现实;现实中的一切都是对象,他们有分类,就产生了"类〞; 他们有不同,类和类之间的不同,使用类来区分;同一个类中不同的对象的区别,使用 成员区分。所以,面向对象的内部逻辑是分类。 面向对象编程思想就象数学上的一些概念,如:空间、群、环、域等原始的编程思 想就象古典数学,人们只在一个集合上探讨问题,没有系统的方法〔即运算〕定义,于 是仁者见仁、智者见智,这样在一定程度上造成了理论的一种混乱局面,不利于科学的 发展。于是近代数学向公理化发展,这是什么意思呢?就是说,人们除了在限定论域〔 即上面的集合,面向对象也有此概念〕外,还在此论域上加进了一套通用的、公认的运 算〔方法〕;集合加上集合上定义的运算就构成了数学上的空间、群等,在计算机领域 里,就变成为"类〞。这种集合上定义了操作的东西利用起来就方便多了,这使得人们讨 论问题时都在给定集合的运算能力上下工夫,即有通用性可事半功倍。面向对象编程 思想就要想近世代数的分析思想,首先要确定"论域〞,即工程所涉与到的所有的"对象 〞,然后要分类处理,把隶属同一类别的对象集合在一起〔做成一个集合〕,定义他们 之间的运算性质与可以进行的操作,这样就构建了一个类,当然以后用到这个类的对象 时都要通过已经定义了的操作来完成各项功能,这就是常要求的类的"类的成员变量要通 过共有函数来操作〞。 我想真正的面向对象编程思想不应该是编程思想,应该是面向对象的分析方法才对 ! 我的理解:1、将分析过程为抽象的过程:简言之:分成多个小问题〔组成部分〕, 直到无法再细;2、对每个对象〔小问题〕进行分析,抽象,提取处共同的内容〔数据成 员和操作方法〕,3、有相似的对象的,构造基类;再有基类派生出各个确定的对象〔小 问题〕;4、解决问题的过程就是操作这些对象的过程。 我的理解: 与实际生活联系起来。将要处理的'问题'抽象成一个或多个'事件' 找一个地方使用我的 智慧1。了解系统的功能。列举出它的对外接口,即对于使用者来说它有什么功能。把这 整个系统作为一个对象。2。环境。系统不是运行在真空中的,操作系统等外部环境都可 能会影响它。所以把环境也作为一个大的对象。3。内部。在系统的内部,一般都比较复 杂,一般的做法是规定一个粒度,枚举出该粒度上所有的物体。比如说人体,如果在器 官的粒度上,就有心,肝,肺。而小于该粒度的物体〔或称对象〕,比如血细胞,就忽 略,作为其它物体〔或称子系统的内部对象〕。4。子系统。不断缩小粒度,沿用步骤1 ~3,直到不能再抽象为止。5。无形的物体。一个完整的互连的系统需要许多无形的物体 ,比如消息等了,一般这样的对象比较难发现。当你发现各个子系统无法正确合作或理 顺关系时,试着加入一些辅助对象。一切都是为了让人明白,有能让机器理解的思想我 想分析和抽象能力的高低是个关键,首先要从问题域分析和抽象出准确的对象模型,再 根据这些模型进行处理,当然在过程种少不了楼上前辈们说的一些思想和细节,但是别 忘了,我们的目的是解决问题,不要为了面向对象面向对象!我想分析和抽象的能力 对这个问题是个关键。首先要在问题域仔细分析、抽象得到相关的对象模型,然后才是 相应的设计。可是面向对象只是我们解决问题一种思想,切不可忘了问题本身,弄成为 了面向对象面向对象了!当然过程种少不了楼上一些前辈说的思想和细节了。 耕具我多年的实践:面向对象包括两个思想:从大往小想,从小往大做从难往易想 ,从易往难做同意一下观点----- 能深入浅出,真高手也!真正的面向对象编程思想就是忘掉一切关于计算机的东西,从 问题领域考虑问题, :- )把问题从大到小都抽象成对象〔指针只是对象的使用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值