问题补充: 方法本身就有问题?方法过时了?程序员不掌握?工具不支持?
容我黑一波Java!Java简直就是对OOP概念滥用的极致。其他语言里,OOP是为程序员服务;Java里,OOP是为程序员添堵。
对于程序员来说,最苦恼的事情就是数据和程序如何和谐共处的问题,这两者是密切相关的,数据的定义改了程序就要修改;反过来,程序的功能变了,数据也要修改。但是数据和程序的定义方法是两种不一样的语法,如果分开来写,谁也不知道哪段程序和哪段数据是相关的了。
C程序员表示脑容量足够,分开写就分开写
C++程序员把数据和程序合在一起写了一个class。做不到的时候他们还是用C程序员的办法。
Java程序员要更加高瞻远瞩一些,他们是这么看这个问题的:数据和程序应该享有相同的权利。
Java程序员把数据加了一大堆getter和setter,然后把程序写进了一个static class,于是他有了两个类。他对此感到很满意。在Java的世界里,数据和程序都是class,这代表了公平和民主。
后来Java程序员对有main函数的class非常不满,觉得这侵犯了其他class的平等权,于是他们发明了JavaBean。从此以后他们再也不知道自己的程序究竟有多少个入口了。
Java程序员对没有implements的class感到恐惧,这代表它不能充分的实现多态性,调用这个类的代码不能正确调用其他有相同功能、相同接口的类。于是他给每个class创建了一个接口一模一样的interface。实际上这个interface从此以后再也没有其他class实现过。每次修改接口的时候,还要两个文件一起修改。
Java程序员极端排斥使用Object类型的指针,这代表自己对这个类型一无所知,甚至无法区分这个类型是自己定义的class还是别人定义的class。后来他定义了一个叫做MyObject的interface,再让所有的interface继承这个interface,再让所有的class实现那些继承自MyObject的interface,确保所有的类的实例都可以转换成MyObject类型。他感觉好多了。
Java程序员想用一个接口抽象出自己所有类的生命周期特性,来实现究极的多态。这个接口有start和stop两个方法,文档规定返回true表示成功,返回false或者抛出异常表示失败。最后99%的类的实现中,这两个方法的实现都是:return true;
Java程序员对单个方法的实现超过10行感到非常不安,这代表自己的代码可重用性很差。于是他把一个3个参数的长方法拆成了4个子过程,每个子过程有10个以上的参数。后来他觉得这样很不OOP,于是他又创建了4个interface和4个class。
Java程序员喜欢思考哲学问题。他之前思考一个问题思考了一个星期,这个问题是:创建服务究竟应该是Server类的方法还是ServerManager类的方法。后来他决定,创建服务完整的流程应该是ServerManager的方法,但其中把服务注册到Server的过程应该是Server的方法。之后的一个星期他在考虑这个方法究竟应该是私有方法还是公有方法。
Java程序员发明了很多设计模式,用来把不OOP的问题转换成OOP的形式,只需要多写两倍的代码。
欢迎一起黑!
使用起来不理想,应该是没领悟到面向对象编程的理念。
常见的理论,三大基本特征、六大设计原则、二十三种设计模式。
三大特征是继承、封装、多态。
六大设计原则是单一职责、里氏替代、接口隔离、开闭原则、迪米特法则、依赖倒置。
二十三种设计模式,具体有哪些题主自行度娘,此处不一一列举。建议掌握几个常用的,如工厂模式,单例模式,适配器模式、观察者模式。
系统学习完上述几点后,你一定会有豁然开朗的感觉。
面向对象编程范式在意的是可修改性和可重用。如果你没这个需求,那么你就会觉得累赘。反过来如果你有大量这样的需求,你就会发现他的效率太高了。主要还是国内对此认识不够深刻。
我感觉确实应用不理想,很多程序员,有些都是资深程序员了对于面向对象的概念仅仅停留在技术层面上。程序员还是没有理解面向对象的基本概念,即使使用类似Java这种工具,也很难提高效率,更何况Java也被程序员带得走形了。
关于面向对象,我会写一系列文章介绍如何认识世界,可以先读以下两篇,感兴趣加关注。
我总结了一下,当前理解上主要有这几个原因:
- 对于面向对象在系统分析中的作用不掌握,还没有掌握拆分对象、属性和方法的基本原则,对于继承的理解不足,对于重载、多态和接口存在滥用现象。
- 项目筹划仓促,没有业务专家的加入或者业务变化比较大,拆分不好对象的设计不仅不能省力,还会给后期的更改造成麻烦。
- 具体工具语言实现过程中,例如Java和Python,也没有对面向对象提供明确使用规范。反倒是产生了“优先使用组合而不是继承”这样的经验,这是技术上开倒车了。
- ......
当然问题还有很多,但我看了许多面向对象的文章,发现困扰程序员,甚至是资深程序员的主要问题是对世界的认识不正确,就是问题1,不掌握的根源在于对世界缺乏认识论。这里说的认识论包括分类、属性、关系、方法、结构.....等要素之间的关系分析能力。
几乎随便找出一篇面向对象的文章,你都可以发现最主要的问题出在根源上:认识世界不正确。
我举个例子大家就明白了:
我们公司说180天以前的发票不给报销,这是自然语言,一句话就说清楚了。但是引入了一个词叫“发票”,发票包含火车票、住宿票、出租车票、停车发票、饭费发票、旅游发票,发票有个属性叫做发生日期,
if 填单日期-发票.发生日期> 180 天 then 显示("发票日期超过180天不予报销")
......你看,要是没有发票的这个指代作用,我们要费好多话。
一个好的面向对象的程序就是要做到概念(指代范围)明确、逻辑清晰、语句精简。这样才好维护好更改。
两篇别人面向对象的小例子,你有别的文章要分析也可以发给我,我感觉大部分问题都出现在例子上,就是对世界的认识方法上。
例子一:
前几天看了一篇讨论Java面向对象的文章,其中举了一个例子:如何将水生动物、陆生动物、食草动物、食肉动物进行分类,如果把他们都做成动物类的继承,你会发现有的食草水生动物不知道往哪儿放。最后决定动物是类,把食草、食肉,水生、陆生都做成接口,然后问题就成功得以解决。
如何对水生动物、陆生动物、食草动物、食肉动物进行分类,其实你仔细想一下,我们学过的动物学中有水生动物这个类别么?并没有!有什么动物类别么?你想起来初中生物学中哺乳动物的主要特征么:胎生、哺乳。没有这两个特征就进入不了哺乳的类别。
那我们怎么表示水生动物这个集合啊?别着急,集合是一定要通过类别表示么?类别也可以通过属性表示。设置一个生活环境属性:
水生动物={动物| 生活环境=水}
属于对象和属性的分析不合理。
例子二:
在另一篇文章中,设计了这样一个继承关系:也是推导了半天,最后得出结论面向对象不好使。
我们来看一下,父亲和孩子是实体么?这个是对象么?,每个有孩子的人都是孩子,一个老人能管他叫孩子么?那他曾经是孩子怎么办?他对于他父母来说始终是孩子吧?......逻辑晕得一塌糊涂。这么分析是不会有结果的。
我们跳出来看一下,实体应该是人,实例是具体的人。父亲和孩子是实例之间的一种关系。认识到这一层就知道要把父亲和孩子分别做成人的方法:如果是get,返回参数就是找当前对象的父亲和孩子。
小结一下:
如何认识世界、分析世界是一门学问,叫做本体论,是面向对象的哲学基础。
学习语言和语文对编程至关重要,说到底编程语言还是语言,语言就有自己的规律和特点,抓住规律才能事半功倍。
博士聊IT,感兴趣请关注!
程序员比社平工资高70%?编程的本质是什么?能力强还是分配不公
因为你面向的不是对象,那用起oo来当然有问题。就好比你生活在热带雨林,却让你去规划沙漠绿化,肯定有问题。
首先?面向对象?是一种设计思想?(OOD),如果你面临的问题可以用对象、类的思路去模拟和解决,那你必定可以用OOL来实现它。如果本身模型就建不起来那就别提OOL了。
其次?OOD是自顶向下?的?。一般来说一个工程项目可以不断拆解,拆为多个子系统,大粒度的拆解往往是很适合用OOD的。因为那可以让你很快捋清楚各个子模块的关系和它的属性范畴。
但是拆到很细的粒度的时候,OOD可能会显得设计臃肿(over-design)或者难以分类。这时候你面临的可能是一个复杂行为的处理,那这时候就可以使用面向过程或者面向状态的思想来处理更为妥当。
设计思想永远都不是?一尘不变的?。能解决问题的就是好的。当然目前很多人对架构的理解是错的。我们讨论的并不是一个架构问题。我们讨论的是“结构问题”(Construction)。即一个合适的设计思想组合,应该是清晰的、易管理的、最短路径的。我们不应该刻意去追求一种纯粹感。
所以语言的设计一直在向这方面演变。近些年流行的一些编程语言就支持上述特性。而JAVA相对来说比较古老,早期单纯的面向对象带来了一阵新鲜感,似乎万物可以对象化的确很香。但是真正做工程的时候你会发现前期真的下沉地很快,但是后期就像水杯里的微小颗粒它就是不容易沉淀下去。
最后一点,当下流行的语言一定是适合绝大多数项目?的语言??。一门语言好不好用最简单就是看它到底流不流行。它跟其他商品一样也是市场选择的结果。如果你的项目跟市面上相比没什么特殊,但别人用得很得心应手你却觉得不好用,那一定是你不习惯或者使用方法出现了问题。
我觉得面向对象的编程方法相对面向过程是一大进步,极大地提高了编程效率。
目前流行的函数式编程,也不排斥对象。我最近在自学kotlin,我觉得kotlin集多种编程语言的优点于一身,是最有前景的编程语言,在kotlin中一切都是对象。
没有不理想,现在都是面向对象了,除了底层的。首先是一种思维方式和认识世界的视角。 面向对象体现的是分类,分工,泛化思想。没有这个思想,用不好OO.
面向对象编程并没有过时。
目前几乎所有主流编程语言都是面向对象编程的,只不过叫法不同,有的就是叫对象,有的叫结构体,有的叫类。对象以键值对的形式存在,key是标识,value负责存储。大部分结构体是可以嵌套的,结构体最上层是原点,往往都以语言本身名称命名。原点下面是原生模块,模块下面是小模块,他们以对象的形式存在,我们可以形象地叫他树形结构。对象就是树中的节点分支,负责连接其他节点。对象可以非常直观的描述事物的属性,也可以描述事物之间的联系。
事物是具有两面性的,对象作为很多语言的基础数据类型,也有一些缺点,比如不能描述事物发展的方向,不能描述横向关系。另外对象树查找起来需要遍历节点,效率低下。如果程序中大对象过多,会影响垃圾回收效率,拖慢程序的执行速度。