面向对象与面向过程程序设计方法的比较
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
面向对象与面向过程程序设计方法的比较摘要:区别于一般讲述面向对象技术的文章,本文系统地比较了面向对象技术和面向过
程技术的异同,并着重介绍面向对象技术以及它的封装、继承和多态三个特点,让读者对面向对象有一个形象的理解。然后通过比较和举例,文章分析了OO技术在软件工程中的三大优势。
Abstract:Being different from general articles about object-oriented technology ,
this paper systematically compared the object-oriented technology and the process-oriented technology, and mainly introduces the object-oriented technology and its three characteristics :packaging, inheritance and polymorphism, to make the reader have an image of understanding of object-oriented. Then through the comparison and some examples, this paper analyzes the OO based software engineering in three points.
关键字:面向对象面向过程软件工程
Key words:Object-Oriented Process-Oriented Software-Engineering
一引言
20世纪60年代中期开始爆发的软件危机,使人们认识到大中型软件系统与小型软件系统的本质区别,软件工程以及面向对象编程(Object-Oriented Programming)技术得以应运而生。从最初的SIMULA到如今的C++、JAVA和C#,面向对象程序设计语言已发展为当前最流行的程序设计语言。
谈到面向对象,一个不能回避的问题是面向过程的程序设计思想。作为一种常用的面向对象语言,C++自C语言发展而来,是一种混合型面向对象的程序设计语言,它既支持面向对象又支持面向过程。面向对象与面向过程虽然在设计理念上截然相反,前者是自底向上而后者是自顶向下的,但它俩仍有众多的相似之处。只有建立在深入理解二者的关系的基础上,我们才算是真正驾驭了面向对象与面向过程技术,以便在未来将它们熟练地运用于学习和生活中。
二面向过程的程序设计方法
著名的计算机科学家Nikiklaus Wirth提出了一个公式:程序=算法+数据结构。这个公式很好地诠释了面向过程程序设计方法的核心思想——算法和数据。
更加具体地说,面向过程的程序设计方法称为功能分解,即自顶向下。以两个人下五子棋为例,面向过程的设计方法是先决定二人中谁先手,然后是先手者下一子,判断游戏是否结实,后手者下一子,判断游戏是否结束……可以看到无论是猜先、落子还是最后的判胜负,它们都是一场五子棋游戏中不能再分割的逻
辑单位。程序员的工作是将这些最底层的功能进行编码并测试,然后将这些功能自底向上装配在一起,直到得到一个完整功能的应用程序。
在这种体系中,我们的着眼点是一个个最基本的功能,数据是为了实现这些功能而设计的,它是后于功能的。
当问题的规模不大时,面向过程的设计方法因其逻辑关系明确,实现简单而备受程序员们的青睐。但是当问题规模扩大到大中型软件时,一个项目的代码量不是一个人可以单独完成的。小组的分工与合作成为解决代码量大的方法,但是这又向程序员之间的配合提出了新的挑战,同时数据共用导致的不安全、代码重用率低等问题也阻碍着面向过程的方法在大型软件工程中的发展。这便是前文中提到的软件危机。
三面向对象的程序设计方法
区别与面向过程的“先功能后数据”思想,面向对象的程序设计方法把状态(数据)和行为(功能)捆绑在一起,形成了对象。当遇到一个具体的问题时,我们只需要将一个系统分解成一个个的对象,同时将状态和行为封装在对象中。
此时我们回过头再考虑五子棋游戏,作为一个系统,它可以被我们分解成若干对象,一种思路是分成棋盘、棋子和玩家三类。或许在这个简单的例子中,OO的优势并不明显,但是在一些大型的系统中,第二种解题思路会清晰得多。
人们总结了面向对象的三个基本特点:封装、继承和多态。
1 封装
封装是一个用来指代将对象的状态和行为捆绑到一个单一逻辑单元的机制的正式术语。它不是面向对象语言所特有的,面向过程的C语言用结构封装了数据,函数封装了逻辑。但是面向对象封装了两者,从这种意义上来说,面向对象的封装更加完美。
出于一些安全性与方便性的考虑,对象经常会限制对它们特征(包括属性和方法)的访问,这种限制称为信息隐藏。作为对象的抽象,类通常只公开对象可以公开的东西,主要是一个特定对象对系统的服务,而隐藏执行服务的内部细节和为了完成这些服务而设计的数据。注意这不是说面向对象和面向过程一样是数据后于功能的。在面向过程中这种先后关系是贯穿全局而在面向对象中,即使存在先后关系也仅仅是在一个具体方法中,对于那些来自外部的调用来说它们是平行的,因此在OO中我们不讲状态和行为的先后关系(有一种说法是状态先于行为,即功能先于数据,但这也不同于面向过程)。
封装和信息隐藏带来的好处用一个例子来说明最恰当不过。著名的Y2K危机指电脑从1999年跨入2000年时,造成年序错乱而引发的一系列问题。第一代计算机在设计时出于节省空间的考虑,将西元年缩为后两位数字,之后的历代计算机都沿用了这个习惯。到了2000年人们不得不面对一个日期格式从2位增至4位的问题,据统计有数十亿美元的资金被用来找出和修补那些可能会造成惨重损失的连锁效应。
在面向过程的设计体系中,数据在全局范围内共享,日期这个数据可能会从
程序伊始到结尾都在被访问,因此数以千万计的代码都要被修改。危机!而在面向对象的体系中,一个一百万行的工程可能只有一个一百行的类会涉及到具体的日期格式,其余的N多行代码纵使出现日期也只是对日期类公有接口的调用,不会出现因为日期格式改变而引发的问题。这种变化带来的影响充其量只是一个工程的日常维护。
2 继承
继承是定义新类的一种机制,使用这种机制创建新类时只需要声明新类和已创建类之间的差别。
对于一个特定的继承关系,我们将创建的新类称为子类(subclass),被继承的原始类称为超类(superclass)。子类可以使用超类定义属性和方法,也可以自己定义新的属性和方法。超类的特征不会受到子类的影响。
继承带来的第一个且是最显而易见的好处是减少了代码冗余,因此也减轻了需要改进或重写代码时的负担。
进一步地,子类会比不使用继承时更加简洁,这点应当不难理解;通过继承可以不加修改地重用和扩展已经彻底测试的代码,这避免了工程性的组装对已经完成测试代码的影响;最好的一点,即使没有已有类的源代码,仍然可以从已有的类中派生出新类,只要我们拥有那个类编译后的字节码。
有了继承的机制,程序员们彻底告别了过去那个事必躬亲的coding时代。20世纪90年代初期,当时正在加州大学埃尔文分校攻读博士学位的Douglas Schmidt在观察了他所参与的软件项目开发实践之后,得出一个结论,即未来的软件开发将越来越多地体现为整合(integration),而不是传统意义上的编程(programming)。换言之,被称为“软件开发者”的这个人群,将越来越明显地分化:一部分人开发核心构件和基础平台,而更多的人将主要是配置和整合现有构件以满足客户的需求。整合依靠的技术,其中一项正式继承。
3 多态
术语多态指的是属于两个或多个不同类的对象以各自的类相关的不同方式响应同一消息(方法调用)的能力。同一个消息根据发送的对象不同而采用多种不同的行为方式。换句话说多态使得消息发送者能给一组具有公共接口的对象发送相同的消息,接收者做出相应的回应。
多态的作用:增强了代码的可读性、操作的透明性,增强了代码的灵活性和可扩充性。
四面向对象在软件工程中的优势
总结前文的基础上,针对面向对象技术在软件工程中的垄断地位,我总结了三个原因。