范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

面向对象编程,为什么这么多人讨厌它?

  "我是旧时代的残党,新时代没有承载我的船。"
  如果面向对象编程是一个人,我猜他自己在不断被非议的今天,一定会这样感慨。
  说实话,我用面向对象方式编程已经十几年了,我做架构设计离不开它,做系统分析离不开它,编码的时候更是严重依赖它,我对面向对象无论是思想上还是写代码上都是有很深的感情。
  刚学 Java 的时候,我觉得面向对象编程(OOP)真牛逼,用面向对象方式写出来的代码是最好的代码。但是随着项目越做越多,代码越写越多,我发现 OOP 不是万能的,盲目地迷信追求 OOP 会有代价。
  今天这篇文章我不是说面向对象不好,只是希望大家不要过度神话它,更不要人云亦云。
  大家都听说过:
  面向对象的三大特性:继承、封装、多态。
  但其实这个说法有问题。面向对象的思想里没有任何继承和多态的概念,正确的说法是:
  这三大特性是面向对象语言的特性,而不是面向对象理念本身的。
  面向对象语言是面向对象设计思想的一种实现,面向对象语言为了能在真实世界使用,其必须经过一些拓展和妥协,而问题也就随着这些拓展和妥协而来。
  1. 继承带来的也可能是无以复加的痛苦
  在实际开发中,我们无论谁写代码,都要考虑代码的复用性。面向对象的编程语言作为给开发人员使用的工具,它也必须考虑到复用性。
  所以,在面向对象编程语言里,对面向对象的基础思想做了拓展,搞出了继承这个概念。
  继承就具体实现来说,就是子类拥有父类的所有非 private 的属性和方法。继承的出现能够最大化地代码复用。
  当项目里一个类已经有了我们需要的属性和方法,而我们现在的需求只是在这个已有类的基础上有些许的不同,我们只需要继承这个类,仅把这少许的不同在子类中实现即可。
  但是如果你用了继承,你就引入了问题。
  继承的出现天然会使得子类和父类紧耦合。也就是说,父类和子类是紧密关联的,牵一发动全身。
  如果现实世界里,所有业务模型都是有层次的,而且层次井然有序,是一颗天然的树,那这种紧耦合没有什么问题。
  但是现实的需求可不是吃干饭的!
  咱们看看这样一种情况。假设现在我们一家只有两口人,即只有父亲和孩子,那么类继承模型很容易模拟这种情况:
  我们在现实生活里,往往是三口之家:
  那这就有问题了。就像小时候经常有人会问孩子,你觉得你是爸爸的孩子,还是妈妈的孩子啊?如果你要用 Java 的规矩回答,只能从是爸爸或者妈妈里选一个,那么完蛋了。回答爸爸的孩子,妈妈不高兴;回答妈妈的孩子,问题更严重,隔壁老王?
  但是,如果像 C++ 那样,你说我既是爸爸的孩子也是妈妈的孩子,也有问题。
  假设爸爸类有个方法叫说话,妈妈类也有个方法叫说话,你作为继承了他们的孩子类,自然也会拥有说话这个方法。问题来了,你所拥有的说话这个方法到底来源于谁?
  另外咱们说了,继承会把子类和父类紧耦合,一旦业务模型失配,就会造成问题。
  这里给出一个维基百科举的经典例子,来说明一下:class Super {
  private int counter = 0;
  void inc1 {
  counter++;
  }
  void inc2 {
  counter++;
  }
  }
  class Sub extends Super {
  @Override
  void inc2 {
  inc1;
  }
  }
  你看,子类覆盖了父类的 inc2 方法,但是这个 inc2 方法依赖于父类 inc1 的实现。
  如果父类的 inc1 逻辑发生变化了,变成下面这样:class Super {
  private int counter = 0;
  void inc1 {
  inc2;
  }
  void inc2 {
  counter++;
  }
  }
  这就会出现 stack overflow 的异常,因为出现了无限递归。
  所以,当我们在子类里,依赖了父类方法作为子类业务逻辑的一个关键步骤的时候,当父类的逻辑修改的时候,必须联动修改所有依赖父类相关逻辑的子类,否则就可能引发严重的问题。
  用继承,本来是想少写点代码少加点班,结果……用网上看到的一句话说就是:
  一日为父,终生是祖宗。
  像这种情况该怎么办?
  现在只要是个正经的介绍面向对象的技术文章或者书籍里,只要是涉及到继承的,都会加这么句话:
  尽量选择对象组合的设计方式。
  在《阿里巴巴Java开发手册》中就有一条:
  组合和继承的区别如下:
  其实我认为继承和组合各有优缺点,如果两个类确实非常紧密,就是存在层次关系,用继承没问题。
  之所以有"组合优于继承"这个说法,我个人感觉是组合更灵活,而且能防止被人滥用,用不好的话轻则类的层次失控,重则很可能就把整个项目的代码质量给腐蚀了。
  2. 封装如同带有漏洞的封印,可能会逃逸出魔王
  封装,说白了就是把属性、方法,封到一个对象里,这是面向对象的核心理念。
  嘴上叫封装,却开了个缝儿。
  我们知道,项目是既要兼顾代码质量,还要兼顾运行性能的。不可能说为了提升什么松耦合、高内聚,就不管不顾性能了。
  事情就坏在了这个兼顾性能这里。面向对象里,以上帝角度看,系统就是对象和对象之间的关系构造成的网络。
  就拿咱们上面谈到的组合关系来说,组合关系的实现就是通过把一个对象当成另一个对象的属性来实现的。
  上面这图就叫做 A 和 B 之间是组合关系。想用 A 对象里的 B 对象,代码这么写:A a = new A;
  B b = a.getB;
  好,我们要问了,这个从 A 中获取的 B,是 B 对象的实例还是实例的一个引用指针呢?
  必然是引用指针吧,这是最基础的知识。诺,问题来了,引用指针是可以修改的。b.getS; //原来是Hello World
  b.setS("World");//直接改成World
  原来 B 中有个字段 s,值是 "Hello World",我直接可以用代码改成 "World"。
  如果这次修改随意在个犄角旮旯里,A 能知道吗?A 蒙在鼓里,还以为一切尽在把控当中呢。
  你看,封装的缝儿出来了吧。说句实话,就这种鬼操作,是非常难以排查的。
  像这种封装了,但是又没封装的问题,我只想说"封装得挺好的,下次别封装了"。
  3. 多态好,但可能是面向对象的贪天之功
  再说说多态。
  其实,面向对象中的多态使用,才是面向对象语言最被认可的地方。因为有了多态,代码才能保证在业务需求多变的情况下,保证了项目的相对稳定。
  可是,多态不是面向对象独有的啊。面向过程、函数式编程也可以。面向过程里,C 语言可以靠虚函数在运行时加载对应的函数去实现多态。函数式编程也可以通过组合函数去实现多态。
  所以,面向对象连多态这种优势都不独特了。
  4. 服务端业务变了,人们的观点发生变化了
  在说服务端业务的变化之前,我想先普及两个概念,即有状态的服务和无状态的服务。
  有状态的服务就是说,服务需要暂时存一些和客户端相关的数据,以便客户端后续发来的请求可以和客户端前面发的请求通过服务器端关联起来,从而共同完成一项业务。
  无状态的服务是说,服务端不存储任何和客户端相关的数据,客户端每次请求,服务端都认为这是个新客户端,和以前的请求无任何关系。
  用现实生活举例的话,有状态服务就是你去一家健身房,第一次去的时候花了一笔钱办了一张健身卡,你以后每次去健身,有卡就不用再掏钱了。无状态服务就是,你没办卡,每次去都和第一次去一样现掏钱。
  那么,无状态服务和有状态服务与面向对象的衰落又有什么关系呢?在如今的年代,分布式、微服务大行其道。一个有状态的服务是不容易做分布式和做弹性伸缩的。
  当年,大家做有多个步骤的业务的时候,为了保证业务数据不会因为用户偶然的关闭浏览器或者浏览器崩溃等问题而丢失,往往会把上一个步骤的信息存在服务端的 session 里,而现在则会倾向考虑把信息放在客户端的本地存储上。
  我举个例子,假设现在有个需求,要在后台系统新增加一个功能:用户信息管理。其中有个需求要求这样操作,录入用户信息分成两步。
  第一步,录入用户的基本信息:姓名、手机号、年龄……
  第二步,录入额外信息:家庭成员、教育经历、工作经历……
  出于信息完整度的考虑,业务要求这两步应该是一个完整的事务。要么都成功,要么都失败。
  从技术实现上讲,如果是多年以前,我们会在第一步的时候,把商户的基本信息做成表单提交,然后为了保证不会因为用户误关闭浏览器等意外问题丢失中间的数据,保存在对应的 session 中后,在第二步信息提交后,合并起来一起存入到数据库中。
  但是,现在的技术趋势是,做任何事情,尽量让服务器端无状态,也就是不存储客户端相关数据。
  此时,这个需求的解决方案就是,当第一步填写商户信息完成后,直接把数据存储在客户端的本地存储里又或者直接就存在 cookie 里,在第二步填写内容完毕后,联合存在客户端的信息一起提交到服务器端,然后存入数据库。
  所以,你看到了,现在大家的趋势就是服务器端都在转向无状态服务,哪怕以前是有状态的服务,也会通过一些增加客户端参数等手段,去改造为无状态服务。
  说了这么多,那这种技术趋势的变化对我们的面向对象有什么影响呢?
  影响在于,服务端现在越来越变得往单纯的处理数据这个方向发展。当仅处理数据的时候,服务器端真正的需求其实就是计算,然后就是为了大幅度提升计算速度,而带来的并行化需求。
  而面向对象这种方式和我们当今的技术趋势是有一些冲突的。
  首先就是确定性的冲突。
  我们的首要需求从以前重度处理业务状态加业务数据变成了业务数据的计算,而计算是需要确定性的:即给定相同的输入,经过服务器端相同的逻辑处理后,应该给定相同的输出。
  而面向对象这种方式,出身在有状态服务大行其道的年代,它会优先考虑业务逻辑的调度,其次才是计算,所以,面向对象是拥有状态的。面向对象的状态就是它的字段值。这些字段值,如果单纯的从计算数据角度看,他们不仅无意义了,反而还引入了风险。
  比如,我们不小心把一个对象的状态给共享出去了,那当我们用同样的输入计算的时候,很可能由于状态的变化,导致了不同的输出结果,最后就是项目出了问题。
  其次,由于计算,我们对性能更加看重了,又由于无状态服务的大量使用,所以,并行的重要性也远远超出了以前。而并行,要求的是结构的开放,和更加严格的无状态化,而面向对象,恰恰严重依赖于状态,并且,他还把这种状态依赖封装在了复杂的对象关系里。
  A 状态依赖于 B 的状态,B 的状态又依赖于 C,而这些依赖,全部被封装在了 D 对象的实现细节里,这种严重的反并行也是现在越来越多人开始反感面向对象的重要原因。
  结尾
  说了这么多面向对象的坏话,其实真的是面向对象自身的问题吗?并不是。
  首先,面向对象其实就是我们程序员试图简化这个世界,提高对这个世界的认知的一种美好愿望而已。愿望来自于人自身认知的局限性,所以本身就不可能完美。
  其次,面向对象编程语言只是一种工具,工具的使用的好坏还是要靠人的,不可能每个人能把一套工具用得完美无缺。
  如上所说,面向对象的问题本质还是人的问题,而人可能永远都需要通过组合使用越来越多的类似面向对象的这种并不完美的工具去解决自己的问题。
  所以,我们不能一味地依靠面向对象,认为面向对象就是最棒的,也不能发现面向对象可能应付不了某些业务场景了,就开始极端地摒弃它。
  我们要灵活地、合理地使用任何我们可以使用的编程思想、编程工具,积极地去拥抱变化。
  不要忘了我们写代码的初衷。
  来源、作者 |:四猿外

特斯拉不去做的,比亚迪要实现了,续航1000KM,充电5分钟跑150KM关于纯电动汽车,大部分人对于续航以及持续续航问题都比较看重,认为这是电动车未来能否替代纯燃油车成为行业主流产品的关键,在这一方面,特斯拉一直被看作是能率先完成突破的车企,而且在去年今年双十一为何静悄悄?双十一,依旧在,今年朱颜改双十一关注度已经大不如前。中国网友疑问今年双十一静悄悄,什么情况?第一没有现象级活动出现。一场活动,要有氛围,需要人人参与。想要人人参与,就需要有现象级活双十一期间,1500到2000以内最值得购买的手机阅读本文前,请您先点击上面的关注,这样您就可以继续免费收到最新文章了。每天都有分享。完全是免费订阅,请放心关注。感谢大家的阅读,喜欢小编为你精心编辑的文章吗?欢迎留言评论,小编都会不买小鹏汽车的N个理由中国互联网造车三剑客去年的股票涨得让人传统车企仿佛已经成了时代的弃儿。但对消费者来说,买不买新能源汽车显然不能只看股票涨得猛不猛,股价漂不漂亮。作为三剑客代表之一的小鹏汽车今年可谓2021年9月日本电商市场watch品牌销量TOP10在日本电商平台,智能手表品牌中不乏中国身影,比如HUAWEIxiaiomiamazfit均为中国产品。但同欧美一样的是,苹果在日本市场也占据着霸主地位。从本次的排名来看,苹果的地位碧然德双十一剁手推荐超简易的碧然德OnTap龙头净水器它来啦11月11日,一年一度的双十一迎来了它的第13个年头,13年来,从传统的折扣季大促销到如今的新消费时代,传统消费观念和消费习惯正在被重塑,与此同时,随着年轻消费群体的不断涌现,消费喜欢打游戏的可以选这三款手机,价格都在2500元以内第一款realme真我GTneo2T(OPPO品牌)realme作为OPPO的子品牌,一直以来都主打性价比,销量都非常不错。这款手机搭配了天玑1200AI5G处理器,支持120hz到今天都是顶级的旗舰配置的手机,你会喜欢吗?一加在以前是没有任何人听过的品牌,后来发布了一加一代,当时一加手机本着只做精品性能高通骁龙801,性能超高,正是这样的精神为一加手机打下了不错的口碑,一加手机有着精简的系统H2O,iphone13min简单测评,究竟值不值得购买近期有小伙伴私信我问13min怎么样值不值得购买其实问的绝大部份都是女生,主要是中意粉色其实有好多人看到13min发布的时候,有不少人在网上发言,哦这不就是我的粉色公主吗这不就是为支持快充,最高续航240公里,这3款新出的电动车,适合跑外卖请您在阅读前,先点击上面的关注。感谢您的支持,我们将为您带来更多有价值的内容。近两年,越来越多的车主想要购买一辆长续航电动车,尤其对需要长途出行的人群来说,长续航电动车能有效保障工格力大松手机已发售大家如何看待董明珠进军手机界的这款手机TOSOT大松是珠海格力电器股份有限公司旗下的专营品牌之一,主营生活电器。机身设计方面给人的第一印象就是似曾相识,有种魅族18X的感觉,又有一种锤子手机的感觉,配色和造型朴实大方。
对于华为手机,华为5G信号,麒麟9000芯片的看法看了这么多评论真的有点脑袋疼,给大家把思路捋捋1高通不用给华为交专利费,华为需要给高通交因为234G信号高通掌握绝大部分专利,只要用就必须交,但是绝对比其他厂商少,因为本身华为自己P50就这?太便宜了吧在缺席了小半年之后,华为P50系列终于正式与大家见面,作为一款本应该在2021年上半年发布的旗舰产品,由于芯片问题一直拖延到7月29日才发布,华为属实是遇到了难处。而随着华为P502021年可以闭着眼睛买的两部手机,配置好颜值高,两年不过时iPhone12iPhoen12是618线上大促的冠军,销量高达180万台,好评95。如果想买一部能用很久的手机,可以选择这一款。另外,苹果将于9月发布iPhone13,为了给新机震惊!猫为流体被科学证实猫咪为液态已被科学家证实并获诺贝尔奖具体是这样的某天,来自法国里昂大学的科学家MarcAntoineFardin马克安托万方丹,发布了论文猫的流体力学研究。华丽丽的斩获了搞笑诺贝尔奖物理学奖,以及100亿的奖金哟!虽观东京奥运首日的感受我想说道2020东京奥运会,大家都不陌生了,观看完开幕式之后,感觉和2008年的北京奥运会简直没得比较,差距一目了然。可谁又能想到此次的东京奥运会场馆在还能看到北京奥运会时期的媒体手机推荐300元价位手机推荐(参数与体验报告结合分析)前面我有介绍过100和200元左右的手机推荐(在我的主页,有兴趣的可以去看看哦!)今天来说说300左右有什么值得买的手机吧300元价位手机分两篇,这是篇本期推荐的是红米note5红苹果iPhone13的杀手来了,库克没料到,这家中企出手这么狠iPhone系列手机自进入我国市场以来,就迅速收割了一大波粉丝,以至于每次面对苹果新品发布会,国产厂商都会退避三舍,以免自取其辱,而近些年敢于正面硬刚苹果的,或许也只有华为了。可惜1000台!关于光刻机,ASML比我们更着急?光刻机作为芯片制造的核心设备,可谓是现阶段科技圈里最被热议的话题,因为它关系着我国芯片产业的国产化进程,是华为等中企解开芯片封锁的关键一步。全球最先进的光刻厂商是荷兰ASML,它几国产厂商集体沉默,华为上线鸿蒙套壳系统?倪光南的呼吁该重视了在二十年前,时任科技部长的徐冠华就一针见血地指出了国内信息产业缺芯少魂的短板,并表示这是架在国产芯片产业脖子上的两把利刃,芯指的是芯片,魂指的是操作系统。没想到这么快就一语成谶,华认输了?美批准610亿美元技术对华为出口,任正非正式表态华为5G技术的崛起,一举打破了美企在通信领域数十年的主导地位,这让老美深感不安,担心未来会有更多的领域受到中企的冲击,于是在这两三年的时间里对华为发起了接连4轮打压,比如造谣华为设听得懂看得远跑得稳,高通携手伙伴,用5G加持汽车新能力过去,普通消费者对于5G的认知,大多在手机等消费终端层面,而经过商用两年多的发展,随着5G网络急速大面积覆盖后,5G也已经逐渐渗透到了各个垂直行业领域,带来了万物智能互联的时代,其