不要迷信面向对象

还记得以前刚开始学编程那会,还不太理解面向对象,后来第一次弄明白面向对象的概念的时候,觉得这个棒极了,将所有问题都抽象成对象来解决,再后来再接触设计模式的时候,觉得简直精妙极了。但是今天我想说的是,不要太过于迷信面向对象,它也有局限性。

面向对象可以令很多问题分而治之,划分对象,对象之间通过接口沟通,对象内部解决自己的问题,降低问题的复杂度和代码的耦合度。这种模式这么好,它会有什么问题呢?以前我也从来没有想过这个问题。直到来到西山居,参与九天神话项目。这个项目与西山居以往项目一个很大不同在于lua的大规模运用,所以开发过程中基本会以lua为主。习惯了C++编程的人刚开始在用lua的时候会很习惯按C++的风格来编写lua的代码(当然我是以我为例,我相信很多人会跟我一样,因为旁边的人也是这样),但慢慢的,我开始考虑动态语言与静态语言的区别究竟在哪里?

Lua是个弱类型的语言,也就是它不会像C++一样对于函数参数要求严格的参数类型,所以理论上任何类型的参数都可以往函数里头传。其次Lua有点类似于函数式语言,函数其实也是一个变量,可以被赋值和传递,这个有点类似于C++的函数指针,但是实际用起来会发现两者根本不是一回事。然后,Lua的一个最重要的数据结构——表,我觉得Lua大部分代码就是对表进行的操作,再配合一些行为,就可以模拟面向对象的行为。

然后我们的代码也确实是将Lua赋予了面向对象的行为,然后这一方式也确实在解决很多问题的时候非常好用。但是什么东西都物极必反,面向对象亦如此。有部分模块的脚本代码,战场逻辑模块,就是用一个纯粹的面向对象模式来编写的,同时还用了Lua的协程,结果导致的结果是这块代码让新人很难接手。(修改小功能很容易,但要理解整个流程很难)脚本本来就是一个很轻量级的语言,很多语言的设计都是接近自然语言的,为的是什么?简单,易懂,容易上手,灵活,便于维护。但是却硬生生的将C++那套东西搬过来,结果导致这些特性都丧失了。复杂,难懂,不易上手,不便于维护(因为使用了面向对象,导致无法直接重载脚本来实现更改,因为生成的动态对象),除了改功能不用重新编译外,基本上已没什么好处了。这个是后来我在写完活动模块的代码之后深深的感受到的,所以基本上活动之后的模块我就很少再用面向对象的思想来设计了,而是开始改用表的思维来构建模型,这个我总结为语言可以帮助你改变思维的定势。

这是我第一次感觉到面向对象似乎不是那么的无所不能,但是也仅仅是针对轻量级语言,那么对于C++这种传统语言,它又是不是真的那么无所不能呢?飞舟给我们上课的时候说过一句话“越是厉害的程序员写出来的代码越是接近c的风格”,这是什么意思呢?总结出来4个字,大道至简。C是最原生的语言,后来的C++都背上了太多包袱,加了太多复杂特性。而C本身是不支持面向对象的。

倒不是说面向对象不好,既然那些厉害的人都偏向于C的风格,那么也就是很多问题其实不用面向对象也可以解决的很好,我想说的是这个意思,而不是张口就是对象。

今天课上说了一个很典型的例子,并行编程,如果采用面向对象的思想来做,基本没戏,因为内部的实现联系的太紧密。而并行编程要求的几个前提条件是:1、操作简单 2、大规模批量 3、彼此之间不会相互影响。所以基本上一开始就完全用面向对象思想设计的代码基本上都很难实现并行计算编程。问题主要是出在大规模批量上,因为对象的要求就是计算在对象内部处理,所以基本上很难做到大规模批量,同时又保证简单。因为很多计算可能都要依赖于上下文的数据。

另外,今天还有一个收获,句柄的概念,以前虽然在学WIN32编程的时候接触过这个,也了解,但是似乎从来没将它运用于自己的代码之中,之后考虑将我们的活动管理模块考虑引入句柄的概念,这样管理起来应该会更清晰。

 

PS:代码不出bug是可能的,这次培训的核心也就是无错编程,正如飞舟说的,你们现在最紧要的目标不是快速的写出代码,也不是写出很高科技的代码,而是要将你们的代码稳定,保证你们写出来的代码不出错,之后再才是前面的。而我现在的目标就是要在1年内实现我写出来的代码基本保证不出bug,当然事实上它们已经在逐步减少了:)

 

发表评论

电子邮件地址不会被公开。