对面向对象和面向过程的误解
现在很多人认为面向对象思想的出现要比面向过程晚很多,其实这是错误的!早在1967年,Alan Kay就提出了面向对象的概念。虽然面向对象出现的如此地早,但是其“工业化”进程要到20世纪90年代了。
现在,有很多人认为面向对象与面向过程是格格不入的,而且C语言无法写出面向对象的代码。不过在我看来这些言论都是片面的:其实面向对象和面向过程并不矛盾,他们只是互补的关系。面向对象注重事物之间的联系,而面向过程注重过程之间的联系。虽然我们使用面向对象思想来编程时,总是要想着抽象、接口等等概念,但是有一点我们仍旧无法回避——我们的程序要通过一系列的“动作”完成既定的目标,而一系列的动作又需要遵循一定的顺序。而这是什么呢?过程!
其实过程无处不在,即使是面向对象的代码里面也会有面向过程的影子。也许我们应该换一个角度来思考面向对象和面向过程——面向对象更倾向与代码的组织,而面向过程则侧重于过程的实现。
多数情况下,我们使用面向对象的思想来组织代码,而使用面向过程的方法来实现功能。Java在面向对象方面做的已经非常好了,但是我们仍然会发现一些面向过程的影子,比如类的静态方法:
2 …
3}
4
严格地说这无异于C语言的函数!但是有时候我们就是喜欢它。对于一些非常简单的方法而言,直接调用一个静态方法会比new一个新的对象,然后调用其方法要方便得多!一般这种代码多会出现在某些工具类上。
Java中的Integer类中就会有一些静态方法。像parseInt方法,它用来把一个字符串解析成一个整数。或许我们应该先new一个Integer对象之后,调用parseInt方法。不过直接使用代码:
有什么不好吗?反而这种方法让我们的代码变得更少了。
确实有很多人在争论面向对象与面向过程。诚然真理会越辩越明,但是从一开始就带有成见的辩论不会有什么振奋人心的结果。很多人觉得C语言无法写出面向对象的代码,还有人会“鄙视”哪些使用C++编译器编译C语言代码的人。在现代,似乎你要是写出面向过程的代码就不太好意思跟人打招呼似的。
其实这些都是成见!组织很好的面向过程的代码也是很优美的。抛开面向对象理论中华丽的词藻,不要只是看到:类、对象、方法、消息等专业词汇,仔细体会一下自己写过的OO的代码,我们会发现它不过就是一类方法针对某个数据结构的操作罢了。先看一下下面的代码:
p.doSomething(args…);
如果你这样写这个代码呢:
People_doSomething(p, args…);
效果是一样的,而且从思想上来讲也是雷同的。其实翻看一下UNIX的系统调用库,我们会发现虽然是C语言的函数,但其中却蕴含着面向对象的思想。其实如果用C语言也可以写出富含面向对象思想的代码:
2 char* name;
3 int age;
4} People;
5
6void People_new(People* this, const char* name, const int age) {
7 this->name = name;
8 this->age = age;
9}
10
11void People_sayHelloTo(People* this, const char* to) {
12 printf(“Hello %s!"nI am %s.”, to, this->name);
13}
14
诚然上面的C代码看起来并不面向对象,它连起码的类、方法的样子都没有。不过这确实使用了面向对象的设计思想。也许你会说:“这没有继承和多态啊!”但是如果你在People结构中加入一些函数指针呢?其实C++实现多态的方式就是使用了vtable,而vtable与函数指针表格没什么差异。
另外一个例子就是Linux中的VFS的设计。VFS的设计巧妙的体现了多态的思想,当然VFS的实现是用C语言。
现在人们大肆推崇面向对象贬低面向过程可能是由于人们的审美观点的改变。确实,当我们使用Java或者C#来编写程序时,我们就是感觉很舒服。有时用面向对象框架写出来的代码让我们自己感觉很“美”。但是我们也不应该忽略面向过程对我们的启示,或者干脆否定面向过程思想。
当我们仔细回顾自己写过的OO代码时,我们多少会看到一些面向过程的影子,而且会发现这并没有什么错。不过我们可能会因为某种原因而忽略它的存在。