面向过程、面向对象和泛型编程

1、面向对象和面向过程

面向对象是尽可能模拟人类习惯的思维方式,使开发软件的方法与过程尽可能接近人类认识世界解决问题的方法与过程。以事物为中心的编程思想,把构成问题事务分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个事物在整个解决问题的步骤中的行为。

面向过程,也就是结构化程序设计是一种自顶向下逐步求精的设计方法,和单入口单出口的程序结构。分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候一个一个依次调用就可以了。

例如:五子棋。

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

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

区别:主要思维的不同。具体如下:
1)通俗一点说,面向过程是数据加代码的集合,它们彼此之间的逻辑地位是对等的,因此是零散的。而面向对象则倾向于对他们分析,归纳,总结,从而提取出有组织有层次的对象的逻辑概念,并进行封装和隔离。它是一种更复合自然和人类天然认知的思维方式。

2)面向过程是一种直接的编程方法,它是按照编程语言的思路考虑问题。面向对象是一种抽象度更高的编程方法。它把眼光集中在了要解决问题本身而不是语言上,目标是使模块的抽象度更高,可复用性更好。面向对象的目的就是可复用。

3)面向对象采用空间换时间的策略,面向过程采用时间换空间的策略。

2、面向对象和泛型编程

面向对象是对data和operation的封装,是对同类事物的抽象,跟结构化编程相比它更接近自然语言。

泛型编程是对class和operation的抽象,对class的抽象可以说是对interface的抽象,而operation抽象则是对具有同一interface的class的operation的抽象。典型应用STL。

区别:

1)面向对象:封装(数据抽象)是基础,继承是手段,多态是目的;泛型编程:参数化类型(概念抽象)是基础,模板是手段,通用是目的。

2)面向对象是运行时问题空间的多态,泛型编程是编译时算法空间的多态(静态多态)。

3)泛型编程的过程就是一个不断将算法中的共性抽象提升(lift)出来的过程,最终的目的是形成一个最大程度上通用的算法或类。和面向对象一样同为抽象,差距在哪?

    最主要的原因很简单,效率。泛型编程和面向对象编程不同,它并不要求你通过额外的间接层来调用函数,它让你编写完全一般化并可重复使用的算法,其效率与针对某特定数据类型而设计的算法相同。面向对象的多态引入了间接调用。当然,并不是说间接调用不好,有些时候,比如确实需要运行期多态的时候,只能使用继承这样的手段。但当能够利用编译期类型信息的时候,为什么要付出不必要的间接调用开销呢?利用接口来实现其通用性,就付出了所谓的“抽象惩罚”(abstraction penalty)。而C++的模板,就是为了消除这样的抽象惩罚。利用模板编写的函数,对于每一个特定的参数类型组合都有一个独立的,最高效的实例化版本。于是抽象惩罚消失了,而这也正是C++模板库能够真正被工业界广泛用在C++最擅长的领域(重视效率的领域)的重要原因之一。

另一方面,对于每一组参数类型组合实例化一个版本出来的做法增加了代码空间,这是一个典型的以空间换时间的例子,不过对于一门静态并追求效率的语言来说,这个代码空间的开销反正也是必不可少的,因为即便你手动为各种不同的参数类型组合编写特定的算法版本的话,也是付出一样的代码空间开销,而且还顺便违反了DRY原则。此外,由于在抽象的时候不用总想着要建立的接口,所以泛型算法编写起来也更为直观。

C++泛型的另一个好处就是,跟面向对象编程的基于继承和虚函数的运行时多态机制不同,C++模板是非侵入性的。你不需要让你的类继承自某个特定的接口才能用于某个算法,只要支持特定的语法接口就行了(比如只要支持begin()调用)。这也被称为结构一致性(Structural Conformance),意即只要语法结构一致即可。而另一方面,基于接口继承的面向对象多态则必须要显式地声明继承自一个接口,这就是所谓的名字一致性(Named Conformance)。

 

 

你可能感兴趣的:(C++)