为什么面向对象糟透了?

2021-02-13    分类: 网站建设

编程语言“三巨头”Java, Lisp 和C语言在Hello World咖啡馆聚会。
服务员送来咖啡的同时还带来了一张今天的报纸, 三人寒暄了几句, C语言翻开了报纸,突然眼前一亮:“这篇文章的标题写得好啊, 《为什么面向对象糟透了!》”
Java 大吃一惊,居然有人这么骂面向对象?!
他赶紧抢过来,看了一会儿,说到:“虽然我对去世的Joe Armstrong老先生非常尊敬,但是我对他的观点却不敢苟同,你看他说'数据结构和函数不应该绑到一起!'”
C语言说:“他说得很有道理啊,函数是实现算法的,就像一个黑盒子,只要理解了它的输入和输出,就理解了它的功能,而数据结构呢就是单纯的‘声明’,为什么要把他们绑在一起呢?”
“不不不,还是绑在一起好!我给你举个例子,一个栈,如果你把它当成一个完整的对象,那用起来就方便多了。”
C语言不甘示弱:“把数据结构和函数分开也挺好啊!比如我可以创建一个叫做Stack的数据结构,然后写几个对这个数据结构操作的函数。”
Java不屑一顾地说:“你看看你这种方式多丑陋啊。”
C语言寸步不让:“本质都是一样的,你是o.f() ,我是f(o), 有啥区别?”
Lisp也插了一嘴:“还有我的(f o) ”
Java无语,心说这两个家伙就是胡搅蛮缠。突然,他心中一动:我怎么忘记多态了。
Java说:“本质是不一样的,你要知道,o.f()是可以产生多态行为的,这就带来了巨大的好处,我给你举个例子,你有一段业务逻辑,需要把计算的结果记录到文件中,将来还可能会记录别的地方,你的设计可能是这样的。”
为什么面向对象糟透了?
C语言:“难道不应该如此吗?一个函数调用另外一个函数?”
Java 说到:“这里有个依赖的问题,就是businesslogic()不但运行期依赖writeToFile(), 在源码级或者编译期也会依赖。”
C语言:“这不是很正常嘛!”
Java又说道:“不一样, 写入文件是底层的实现细节,不是高层策略,假如用户不想把计算的结果保存到文件中了,而是想通过邮件发送,那你的businesslogic也得修改了,对不对?”
为什么面向对象糟透了?
C语言:“那肯定啊!函数调用嘛,一个改了,另外一个也得改。”
“这就是问题了, 编译期/源代码的依赖导致我们没法把系统划分成独立的组件,各自独立开发,独立部署,一个的变化就影响到了另外一个。”
C语言觉得有一定的道理,他说:“那怎么办?”
Java说:“你看看我使用多态以后的设计,我的业务逻辑在编译时只依赖那个接口Writer,而不依赖具体的实现FileWriter和MailWriter。”
为什么面向对象糟透了?
“你的意思是只要接口Writer不变化,底层的具体实现如FileWriter ,MailWriter可以随意变化,随意替换,就像插件一样,对吧?” C语言说到。
“对啊,编译期/源代码不依赖,运行期依赖,这就是延迟绑定带来的好处,现在你明白o.f()和 f(o)的本质区别了吧。 ”
Lisp 不失时机又插了一嘴:“你那接口中只有一个函数,就是write(),用什么接口啊,脱裤子放屁,多此一举,在我这儿只要把不同的函数传递过去就可以了。”
Java笑道:“别抬杠,这就是个简单的例子,不管是用接口,还是传递函数,都是延迟绑定嘛, 关键点都是要找到那个稳定的东西(Writer),就是抽象。你找不到这个稳定的东西,做不出抽象,你的系统就没法划分成可以独立开发,独立变化的组件了。”
C语言还想反击,但一直找不到突破口。
Lisp说道:“别听Java在哪里忽悠,C老弟,你也能实现运行期的延迟绑定,这不是Java的专利,你忘了虚函数表了?”
C语言一拍大腿:“是啊,我忘了那一年春节回家,Linus 大神曾经告诉我,虚函数表和函数指针才是实现多态的关键,比如Unix/Linux把设备都当成了文件,有标准的open , read 等方法,对于不同的设备,都能调用对应的方法, 那是怎么实现的?也是通过虚函数表做延迟绑定嘛!”
(码农翻身老刘注:C语言实现面向对象的详情可以移步《
C语言高兴了:“哈哈,Java 老弟,看来我们本质上还是一样的,多态只不过是函数指针的一种应用!”
Java说:“所以编程的关键不在于是否使用了面向对象的语言,这一点你同意吧?”
C语言点头,编程的关键点就是找到、抽象出稳定的接口,针对这个接口编程,这样就可以让各个模块能够独立地变化。
“说起来容易,做起来难,这儿有一个例子,你给我用面向对象设计一下?” Lisp 抛出了一道题。
动物可以分为肉食动物,草食动物,水生动物,陆生动物,用类如何表示?
Java 说:这还不简单,看看这名词多明显啊,都可以变成类啊,让他们都继承动物就可以了。
为什么面向对象糟透了?
Lisp看到Java 掉入了陷阱,狡黠地一笑:“那有的动物就既是陆生动物,又是肉食动物,怎么表达?”
“那我就加一个陆生肉食动物类。” 虽然觉得不妥,Java还是说了出来。
为什么面向对象糟透了?
“那要是再来一个水生肉食动物怎么办?或者来了一个新的概念‘哺乳动物’, 该怎么处理?”
“哈哈哈,我懂了,随着需求的增多,不但类会出现爆炸, 还可能会出现那种怪异的类,这面向对象编程确实是有大问题啊!” C语言说。
Java 低头沉思不语,突然,脑海中想起来了那句话:优先使用组合而不是继承。
怎么使用组合?必须得改变下看待问题的方式,对,应该这样:
为什么面向对象糟透了?
Java得意地说:“看看这个图, 动物具备多个特性,如'进食', '移动',将来还可以加上'哺乳方式',每个特性都是一个接口,接口是稳定的, 动物这个概念是可以通过这些接口特性给组合起来的。”
Lisp 赞赏地点头, C语言向Java投去了钦佩的目光,这家伙经常做面向对象的设计,还是有两把刷子的,他通过特性的方式把变化给隔离了, 各个特性可以通过组合的方式,像插件一样随意替换, 嗯,这才是面向对象的真正精髓啊。
夜已深, 最后Java做了个总结,大伙散去。
“编程嘛就是发现变化,并且把它给隔离起来,使用各种语言都可以,面向对象的语言有着直接使用多态的便利,以后不要随随便便就diss它了。”

网站栏目:为什么面向对象糟透了?
本文URL:/news3/100803.html

成都网站建设公司_创新互联,为您提供动态网站网页设计公司微信小程序定制开发网站设计电子商务

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都定制网站网页设计