一、从面向过程说起
1、面向过程:即根据业务需求,按照解决问题的方式一步一步的处理,直到需求完成。人类思考解决问题的方式是符合面向过程的。
2、例子:比如20年前,全国农民基本上自产粮食,就拿稻子举例,种子需要经过播种,萌发,生长,开花和授粉,籽粒的形成,稻谷的成熟,收割,加工和储存等等步骤才能变成我们桌子上香喷喷的米饭。然而整个流程的周期特别长,如果其中哪一个步骤出现问题(比如发生旱灾),那么将有一部分稻米无法走完整个过程。这该怎么解决呢?
3、所以面向过程有一个很明显的问题,整体高度耦合,牵一发而动全身。
二、面向对象的个人理解
1、面向对象的起源:由于面向过程存在高度耦合的情况,而现实复杂事物需要一种更灵活更健壮的组成方式。根据需要任意的更换局部模块,而不会影响全局,这极大的提高了整体的灵活性。也使得整个系统更加稳固。
从数学上分析,面向对象更符合数学证明的过程,对象就是一个个组件,它定义了自己的功能(并保证功能的可用性)。比如这些组件,直角三角形的勾股定理。作为一个外行人,我们只需要知道这些组件提供了哪些功能,然后将这些组件很好的有机结合起来形成一个新的组件。这不就是数学证明的过程吗?所以我们学习一个新的组件时,并不能只满足其表象(包括对原理的理解),而是应从中找出其他方向(视角)的东西(比如设计轮廓,公共部分,推导方式等等)
2、问题:把大象放进冰箱需要几个步骤?
1、把冰箱门打开
2、把大象放进冰箱
3、把冰箱门关上
刚听到这个问题时,我就特别疑惑:大象的体积比冰箱大了好几十倍,怎么能放进去了,怀疑这个问题就有问题?其实这是一种思维惯性,这种惯性导致我们思考问题时总是习惯性的去从可行性方向去思考问题。这种思想方式有很大的局限性。让我们总是关注解决问题的结果,而不是解决问题的过程。从面向对象的方式去思考:冰箱,大象都是一类对象,它们都有各种的属性和行为,如果拘泥于属性的可选范围,那么对象的行为就会失去了自身意义。所以我们将对象的行为抽取成接口,定义接口应存在哪些行为,而不关注行为的具体实现。这样使得面向对象思想大放异彩。
3、以面向过程分析:把冰箱门打开 -> 把大象放进冰箱 -> 把冰箱门关上
4、以面向对象方式分解:
1、分析具体组件:冰箱,门,大象,客户端
2、分析功能组件:可容器(放进去,拿出来),可开关
3、定义接口:可容组件的接口,可开关的接口,可放进的接口
4、定义类:门实现可打开接口和可关闭接口,冰箱实现可装的接口,冰箱应该持有门(耦合-建议持有可开关接口),冰箱应该持有有一个容器,用了盛大象,客户端
5、组织:在客户端中,创建门,用门来创建冰箱,创建大象,调用冰箱的打开方法,调用冰箱的添加方法,将大象放入。
5、再举个例子:假如在未来将会出现人工意识,那么在孵化这一新的概念之前,按可行性方案的思考方式去考虑,是不是以考虑实现为首要任务,这就有点无稽之谈了。以为从这一概念来讲,涉及的各个方面都非常复杂非常深了。比如:什么是意识,意识如何形成,意识如何决策,意识是如何形成有效闭环。但是从接口方向上来看,我们不需要关注人工意识是如何实现的,只需要关注它有哪些行为,比如人工意识应该要有主动性决策的行为,观察外部的行为,执行决策的行为等等。从这一层面上看人工意识就变得简单多
6、百花齐放:在面向过程,每个业务的都是由业务的执行过程和产生的结果,没有不经历过程而得到结果的事物;但是我们可以把过程和结果分离,过程交由他人去执行,我只需要结果。而在面向对象中,我们把过程看作是一个模块,业务调用方只关心结果,而不用关心业务的执行过程,对于业务方只需调用该模块即可,当这个模块出现漏洞时,直接替换成其他模块即可,省时省力更省心。随着分工越来越精细化,可以对该模块拆分,拆分成更多的子模块。子模块还可以根据实际情况(变动可能性)继续拆分成更精细的子模块,而每个模块可以更专注于自己的领域(单一职责),提高生产力。因此,这每个模块,就可以称之为一个对象。模块之间通过沟通协作完成一个整体的任务。当模块足够多,分工足够合理,沟通协作足够良好时,我们便可以完成更大规模的任务
7、面向过程与面向对象的关系
1、它们之间不是对立关系,面向对象并不意味着没有过程
2、它们是进化关系,当我们发现一部分过程可以外包给其他对象的时候,我们的编程思维和编程方式都升级了
三、对象
1、对象:就是拥有一项职责的项目、服务、模块、类、接口、方法等,即万物皆对象,其实我更愿意称它们为组件。
2、对象定义:那些帮助我们完成过程,隐藏细节,压缩多余信息,通过简单的沟通(调用)就可以完成某些功能的角色。
3、什么时候出现面向对象:只要有分工协作的情况。
4、判断代码是否符合面向对象的思想:需要看该对象表现出来的特点是什么。
1、容器:对象具有信息打包压缩功能
2、接口封装:对象具有屏蔽细节简化接口的功能
3、高度可复用:对象具有高度的可复用性
继承它是一种提高对象复用率的手段而已,不是目的。通过继承,保留父类一部分信息,同时保留可扩展的能力,提高生产力(编码效率)的同时对于调用方,对象能否隐藏足够多的细节,使用方式足够简单,并且有高度的可复用性,这种写法更加贴合面向对象的思想
组件化的设计是面向对象思维的一种很好体现
三、面向对象编程的基本思路
核心:根据职责分工来拆分,根据职责来驱动组件的开发
1、梳理清楚一个需求或一个功能的在用面向过程的解决时的整个流程
2、将流程中的步骤进行拆分,拆成一个个对象,每个对象负责整个流程中的一小部分职责。
3、更细化的:
1、确定类:类有哪些属性和方法,构造方法
2、确定接口:有哪些常量和方法,是否能提供默认方法