面向过程(面向结构)与面向对象的区别

相关博客:http://blog.csdn.net/eleanor_12/article/details/51873821

面向结构(过程)的特点:处理具体细微事物的执行效率高,追求实现的过程;

(C语言为典型的面向过程的语言。具体的C语言的特点我在《嵌入式开发为什么选择C语言》一文中作了详细解释)

                

面向对象的特点:(多态、封装、继承)

代码复用性:指的是可以直接调用;

代码扩展性:增加新功能时,不修改原来的代码;

代码维护性:即可修改性,让软件能随着用户需求的变更而容易改变。


先说说结构化方法的主要思想:

(1)功能的分解是一种递归定义。也就是说:第0层(代表整个系统)它只看得见 1,2,3,至于1,2,3各自自身怎么实现,那不是它的事,而对于模块1来说,它只管1.1,1.2,1.3,它并不管1.11,1.12等.这种思维能让我们每次聚焦在一个部位上,这个部位可能处于高层,也可能处于低层,但不管处在哪一层,都是用的迭代的思维,第n层只考虑它和第n+1层的关系,并不考虑第n+2,n+3层。

(2)模块1,2,3之间可能是"与"的关系,也可能是"或"的关系,它们相互协作来完成上一层的功能。

(3)也因为上述的递归定义,所有不管是函数,还是子系统,还是整个系统,都可把该系统分成几个子系统之后,每个子系统仍然是用这个模型来描述。

(4)这个功能分解的层次图如何建立呢?功能分解最终转化为事件的分组,分包。所谓事件就是系统处理的外部用户的请求.注意:这里的事件不是指的用户点击界面上的一个按扭,一个菜单,当然可能是这种情况,界面通常是复杂的,"对话框套对话框",我们看的不是界面是什么,而是用户使用界面达到一个什么目的,这个目的通常才是用户对系统的请求,即"最后一个界面"

一个系统处理一大堆事件(1,2,...n),通过对这些事件进行分组,不同的模块处理不同的事件,最终以事件为线索对系统的功能进行分解。

 

面向对象方法的思想:

整个系统被分解成对象的集合,而不是功能的集合,每个对象有自己的职责,对象之间相互协作来完成用户交给的任务。

(1)同结构化相比,它不是层次结构,在结构化中,上一层依赖下一层,下一层又依赖下下一层,

只要底层改变,上层也要跟着改变,它没有很好的隔离变化.而面向对象刚很好的封装了变化,外界只需使用对象的接口,而不用管这个接口是如何实现的

(2)一个重要区别是:这里的箭头是请求,而不是数据流.在结构化方法的DFD数据流程图中,箭头代表的是数据流,也就是说一个模块的输出变成另一个模块的输入,而这里,指的是对象A请求对象B完成某项任务,也就是A调用B的方法。

 

从结构化到面向对象的两个误区,也就是两个极端:

1.过大的类.一个类中包含了几十个函数,这种大杂烩严重违背面向对象的单一职责原则。也就是说,一个对象要干的事应该和它的名字一致,它要干哪些事,从它的名字就应该能看出来.

2.类中只有函数,没有属性.这是陷入了功能分解的误区,只是简单的把函数组装到一起.基本没有封装。

对象的一个重要特性是:对象是有状态的(也就是属性),对象的行为与它的所处的状态密切相关。


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

 

    最近又有客户问起结构化方法(即结构化分析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方法中继承的原则在这里得以体现。能够突破类的私有部分,禁止其它函数直接访问限制的友员机制,以及由运算符重载、函数名重载和虚函数构成的多形性,使程序员能以更自然、方便的表达方式实现对象的操作。

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

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

结构化程序设计的主要思想是功能分解并逐步求精,当一些任务十分复杂以至无法描述时,可以将它拆分为一系列较小的功能部件,直到这些自完备的子任务小到易于理解的程度。

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

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

    

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

(本文大部分内容是从网上整理所得)



  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值