更多
2017年08月22日 11点56分 叶飞 修改

一起帮里有人问“面向对象”的问题。但我创建“一起帮”的目的是帮人解决“具体的”“实务性的”问题,“面向对象”太过于抽象,所以没批准发布。后来在QQ群里讨论,看他们七嘴八舌闹得慌,突然有一种“多情应笑我,早生华发”的萧瑟之感。

一转眼,我学编程都已经十年了。

十年之前,“面向对象”火得一塌糊涂。

十年之后,“面向对象”,没想到,还是这样云里雾里……

 

回头想想,之所以云里雾里,我认为一个很大的原因:我们把“面向对象”神话了

我今天,就想损一点儿,来把“面向对象”拉下神坛吧。O(∩_∩)O~

 

我现在都还记得,那时候炫耀自己的项目,“纯面向对象开发”……一个“纯”字,顿时逼格满满。现在想来,那时候说话确实不走脑子。“纯面向对象”,还有“不纯”的么?“不纯”的是什么?是杂质,是渣滓?是那些if...else...,是不是应该被剔除?问题是,你剔除了if...else ...,你项目里还能剩下些什么?

不知道大家以前有没有想过这个问题?

我觉得这是一个好问题。“纯面向对象”这种说法背后折射出来的,就是把“面向对象”和“面向过程”对立化,从而把“面向对象”人为拔高人为神话。

 

因为最近动了做培训来推广一起帮的念头,我会这样来思考这个问题:假如我是老师,我会怎么和同学们讲解“面向对象”?“继承”“封装”……No,No,No,那是以后的事。事实上,很长一段时间,我就是被这些东西搞晕了,而没能触及到“面向对象”的本质。

 

我觉得,一步一步由浅入深的理解“面向对象”,正确的姿势应该是这样的:

首先,同学们已经理解了方法/函数,明白为了代码的重用,我们需要一个又一个的函数。

那么,假设我们有一个项目,十万行代码(这其实就是微型项目),按一个函数平均50行计算,就会有2000个函数!好,问题来了,2000个函数啊,别说你记住了,你先想想,你咋命名?呵呵。

所以,一定得想办法,把他们“归类”(大家注意这个“”字):这50个函数,都是干这事儿的;那50个函数,都是干那事儿的……分门别类之后,2000个函数,50个类,这样,是不是有条理得多,清晰得多了呢?然后,调用一个方法的时候,先找到类,再找这个类下面的函数,是不是更流畅一些?比如:Blog.Publish(),Comment.Publish(),Blog.Agree(),Comment.Agree()……你看,也不用担心“重名”了。

这才是对“类”最基本最入门的理解——然而,很多同学,恰恰是缺乏这种最基本的理解,或者理解得不够深入,就直接奔那些“高大上”的概念去了。从而,在开发过程中整出很多莫名其妙的“幺蛾子”来。

可能有些同学不服气,“我怎么就理解得不够深入啦”,“这还需要这么深入理解”?或者,还有一些同学,要教育教育我,“你这个理解太初浅了”,“引入‘面向对象’,是为了‘重用’‘抽象’”,“来来来,我给你讲讲‘设计模式’,高级货!”……

这就是问题所在!有些同学,用了一堆的“高级货”,把本来复杂的程序搞得“更复杂”了。于是,有了所谓“滥用”,“滥用继承”“滥用设计模式”“滥用……”我想,有过一定开发经验的同学一定听说过甚至见识过这种“滥用”的,够酸爽吧?哈哈。那么,怎么才算“滥用”,怎么才能避免“滥用”?

其核心就在于理解一点:面向对象(其实包括所有针对“企业级应用”开发的思路策略),核心目的都是“降低系统的复杂度”,注意:降低,降低,降低,而不是“增加”系统的复杂度。业务需求本身已经够复杂了,就不要再给代码里“添乱”了。

请注意,这里的“复杂”,通常指的是“繁多”“杂乱”“无序”,人脑难以应付。怎么解决这个问题呢?无它,归类而已。

 

好了,回到“面向对象”,我们已经把函数进行了归类,感觉上舒服多了。然而,当代码量进一步膨胀,达到100万级的时候,就是类,也有500个了,我们的脑子还是不够用了。这时候,我们就会问:可不可以把这些类再进一步的归类呢?

当然可以,于是就有了“继承”;在“继承”的基础上,又有了“多态”;有了“多态”,就有了“设计模式”……

这些东西这篇博客我都不想讲,一篇博客也讲不了——太庞大了。

那我想讲的是什么?

是顺序,是目的

 

是先有方法函数,然后才有类;是有了类,然后才有了继承……

或者,更准确的说:是先有了一堆一堆多得让人抓狂的方法函数,才有了类;是先有了一堆一堆多得让人抓狂的类,才有了继承……

更本质的说法:是先有了问题,然后才有解决方案

而我们使用各种工具方法的目的,是为了解决问题。

 

这十年的编程生涯,我其实走得比较顺。(比TM的搞家装强太多了!)如果一定要说“走了什么弯路”,也就是在“面向对象”(以及衍生出来的种种,譬如“设计模式”)上面。

我想,最大的问题就在于:一开始,“面向对象”这玩意儿就是被“灌”进脑子里的,而且你还被不停的灌输它好很好灰常好——但究竟怎么个好法,却很少有人能说得清楚。所以一直晕乎晕乎的,不明觉厉。而且你会自然而然的产生一种心理:面向对象好,没有面向对象就是不好的。

这当然是不对的。

你可以把“面向对象”当做机关枪,机关枪火力猛射程远,但这并不是说机关枪就是最好的,手枪步枪狙击枪都是渣,而是各有各的用途。

这本来很好理解,然后,当你手里有了一把机关枪,而你又狂热的喜欢这把机关枪的时候,事情就变味了。你会说,机关枪一样可以干手枪的活,

  • 我用机关枪比你用手枪还好使,
  • 你觉得不好用,那是你不会用,
  • 不信你看着……

这就走上邪路了。

 

机关枪这个例子,如果现实生活中真有这样的人,你一定觉得他是疯子。

但在IT圈里,其实到处都是这种疯子。隔三差五的各种语言撕逼、框架撕逼、阵营撕逼,本质上,不就这么回事么?

 

矫枉过正的说,“面向对象”,或者“面向对象粉”们,确实有走上邪路的倾向。

如果说你确实能把“机关枪”玩出“狙击枪”的效果,那邪也邪得有个性,溜得飞起!问题是绝大多数人,没有这种本事,邯郸学步,就有些尴尬了。

 

我举一个例子:

现在有两个类,一个用户类(User),一个博客类(Blog),现在有一个发布博客的方法(Publish)。

那么,“发布博客”这个方法,究竟是应该放在用户的类里面,还是博客的类里面?即:究竟是User.Publish(Blog)呢,还是Blog.Publish()?

以下为思考时间:

滴答……

滴答,滴答……

滴答,滴答,滴答……

如果按照“万物皆对象”,“对象映射实体”,“方法就是对象的行为”……之类的格言来套的话,当然应该是User.Publish(Blog),你看,用户发布 博客,一一对应啊!美滴很~~就像我们老师教的那样,名词做对象,动词做方法……

但有过一定开发经验的同学,就知道应该是Blog.Publish(),但为什么呢?这看起来好像不对啊?博客怎么会发布呢?博客自己发布自己?什么鬼?不通啊!

 

确实不通,不过是你自己没“通”;或者,一开始就错了。

要理解这个问题,就得回到面向对象的“起点”,明白“面向对象”要解决的问题,不是什么“映射客观世界”,就这个问题,也还谈不上什么“继承多态”(“封装”勉勉强强,但根还不在这里)。

让我们再回头复习遍:已经有了一堆一堆的方法,再引入一个又一个的“类”,目的是什么?把方法装进一个又一个的类里面,分门别类,是不是为了照顾我们的“大脑”——这可怜的资源有限的人脑?电脑就没这些麻烦,方法都不用,01010010000101001001……就OK了。所以,假设有50个类,是不是每个类里的方法数目都差不多,匀称一些,我们的分类就更有意义一些?

假设User.Publish(Blog)的逻辑成立的话,是不是还会有User.Publish(Comment),User.Agree(Blog),User.Logon(),……,User.FlyToSky()……一个系统,是不是几乎所有的操作,都是User干的?这User不是要上天啊!我们“分门别类”的工作,是不是就没有意义了?以前是记一堆函数,现在是记User下面的一堆函数,有个毛用啊!

 

但我经常看到类似User这样的万能类,有轻重程度的差别,但本质上,这种代码,就是“披着‘面向对象’的皮”,干着……干着什么事呢?干着乱七八糟的事。

当然,还有滥用继承,层层叠叠的像个十八层宝塔一样,又百转千回的像个死亡迷宫一样,你咕哝一句“整复杂了”,架构师一脸傲娇鼻孔朝天,“面向对象,高级货!哪那么容易的……”

 

码字才真心不容易——这博客从昨天写到今天,差不多了。

做个总结吧:

  1. 面向对象,以及所有的软件工程思想方法,其目的都是把复杂的问题简单化,而不是相反。
  2. 所谓“简单化”,指的是让我们人类的大脑觉得“简单”,而不是电脑。电脑?0101010010000010101010……才最简单。
  3. 记住上面两个原则,明白:软件开发的目的是为了解决问题,而不是“炫技”。尤其是不要为了“炫技”而把本来就复杂的问题搞得更复杂……

(⊙x⊙;)

 

就酱紫,我要继续愉快的撸代码去了,欢迎围观。

面向对象 编程 开发 软件工程
支持: 6 反对: 0
您还没有登录,不能发布评论。请登陆注册

评论 / 2
2017年09月04日 11点07分 --- 第 2 楼 --- tangdebing

精选

没有学过面向过程的语言(如C),直接搞面向对象的话,确实不太好理解。

根本上还是思维方式的不同,面向过程偏向于函数的使用。面向对象偏向于对象的使用。

2017年08月25日 12点40分 --- 第 1 楼 --- jpf3888

精选
哈哈哈,初学python的我在面向对象上也始终想不明白,这下不再纠结到底什么是面向对象了。谢谢楼主
关键字

换一批
即时消息

2017年09月21日 11点26分 叶飞

用户wangyan使用了你的邀请码进行注册,系统奖励你 时间币 10分钟

2017年09月21日 11点09分 叶飞

用户高秀格使用了你的邀请码进行注册,系统奖励你 时间币 10分钟

2017年09月21日 00点31分 叶飞

用户使用了你的邀请码进行注册,系统奖励你 时间币 10分钟

2017年09月20日 16点01分 叶飞

用户wujyou使用了你的邀请码进行注册,系统奖励你 时间币 10分钟

2017年09月20日 10点34分 ala741

你感谢了求助HBuilder怎么直接利用网址打包(没有本地项目...叶飞的总结,获得系统 时间币 奖励1分钟

全部消息
新注册用户

2017年09月21日 11点26分
wangyan 男, 1992年10月天蝎座
2017年09月21日 11点09分
2017年09月21日 00点31分
2017年09月20日 23点49分
fanfuhan 男, 1994年5月金牛座
小白…
2017年09月20日 17点17分
小糖 女, 1989年11月摩羯座
更多