变化与不变.
应对变化之道.变化,修改,扩展更方便.
不变的共性才可复用.
越抽象越有共性,易复用,越具体越有差异.
功能越单一越可复用.
越稳定的越可复用.
把复杂的地方分解提炼成类?
易变的地方.
资源:职责,你要完成职责,你拥有相应的权力以及资源,这些完全由你支配.
过程,你不独立拥有支配.资源,要么全局共享,要么作为参数临时借用.
对象具有组织结构.
2,3个人的工作室.大家把资源放在公共的地方,谁用谁去拿,用完了还回去.
或者找正在用的人要.
20,30人,有专人负责专门的资源.用时找其登记,用完归还.
面向对象关心职责与服务划分,该谁去做,做什么.怎么做是由做的人去关心的细节.更像领导.OO:一件事是由相关的对象分工合作完成.一个系统中的对象及其职责相对来说更稳定.变化更局部.
而面向过程:关心产品怎么做.更像基层员工.一件事是由很多步骤完成的.一方面,有时一个步骤的变化,引起相关步骤的变 化.另一方面,过程之间的交互,状态的保持,要么参数,要么是全局变量.全局变量谁都可以修改.而对象对此进行了封装.函数实现功能复用,对象实现职责复用,抽象层次更高.
就像人有思维模式一样.可以用同样的做事的方法,做不同的事.
交互模式:
对象间的交互:以消息.
面向过程:以数据为核心,围绕数据.数据在各个函数间流动.输入,处理,输出.
世界500强的领导跳槽很多跨行.领导才能更通用.
而专业技术人员跳槽比较少跨行.专业细节太多.
就像一个公司.公司架构相对变化比较少,公司产品可能变化比较大.架构相应的是职责.生产产品也是一种职责,但生产什么,怎么生产会变化.铁打的营盘,流水的兵.
使用面向对象的思维方法,其实是一个把业务逻辑从具体的编程技术当中抽象出来的过程,而这个抽象的过程是自上而下的,非常符合人类的思维习惯,也就是先不考虑问题解决的细节,把问题的最主要的方面抽象成为一个简单的框架,集中精力思考如何解决主要矛盾,然后在解决问题的过程中,再把问题的细节分割成一个一个小问题,再专门去解决细节问题。
因而一旦牢牢的抓住了这一点,你就会发现在软件设计和开发过程中,你自己总是会不知不觉的运用面向对象的思维方法来设计和编写程序,并且程序的设计和开发也变得不再那么枯燥,而一个合理运用面向对象技术进行设计和架构的软件,更是具备了思维的艺术美感。
举例:签字.
用两种编程的方式来实现:“我吃饭”这个事件
这是一个很简单事件,我简要的分析了一下:
从面向过程的角度:
首先有一个函数(或者说是动作),那就是吃,然后有两个数据成员:我和饭。然后再在一个函数体里面实现这个算法。
从面向对象的角度:
首先分析发现其中有两种数据,人和饭,这样就产生了两个对象,进而抽象为两个类,然后发现人有一个方法:吃。最后产生一个人类类型的变量我,然后就可以实现这个算法。
如果我们有一种高级语言或者也可以说是直接用伪代码来实现的话,他们各自的伪代码就可以用下面的方式来表示:
面向过程代码:
{
我,饭;// 完成吃这个函数的两个变量
吃{a,b};// 定义一个函数来实现吃这个过程或者说是动作
吃{我,饭};//或者是 吃{饭,我};主要取决于函数内部的实现是a吃b,还是b吃a
}
面向对象代码:
我{
吃()};// 产生一个类我,实现一个方法:吃
饭{ }; // 产生另一个类,饭
我.吃(饭);// 类我的一个变量我调用方法吃,对饭进行操作。
我们从这里就可以很明显看出面向对象和面向过程之间的区别了,面向过程更倾向于事件,他主要是先产生一个事件的核心,中文中其实就是表示动作的动词,然后设定变量来完成这个动作。而对于面向对象,则更接近于现实,他是首先找到其中的数据成员,也就是所谓的万物,找到后万物皆对象,在对每个对象分析找到各自所包含的方法(也就是面向过程中各个对象可以实现的函数或者说是动作)。相比之下后者更容易建模和进行系统设计,尤其是在大型系统的设计中。
如果把这个问题引申或者进一步思考,就可以得到关于面向对象的进一步理解的或者是对其全貌的概览。
之前的事件改为:我吃面,牛吃草,然后还会反刍。
这个时候我们发现对象就有我,牛,面,草。其中我的动作(即方法,为了通俗理解,这里不再使用面向对象的术语)就有吃,牛则是有吃和反刍。我们分析还可以发现其实我和牛就在这个事件的条件下具有相同点,都是动物,都要吃,而面和草对于这个问题中也是具有相同点的,他们都是食物。但是这里为了表现更多的信息,我们不构造食物类。
同样我们用伪代码来实现的话,这个事件的伪代码就可以用下面的方式来表示:
动物 {
吃();
}; // 构造一个动物类,可以实现一个方法:吃
牛 extends 动物 {
吃();
反刍;
} // 构造一个新的类牛继承自动物类并且覆写了动物类的方法吃,而且还有一个属于自己的方法,反刍。
我extends 动物 {
吃();
} // 构造一个新的类我继承自动物类并且覆写了动物类的方法吃,此
时牛和我的吃的方法就实现了多态
面{
} //这里没有将面和草构造在一个食物类里,这样是可以的,但是在这里
意义不大,相反还会增加代码量
草{
}
我.吃(面); //直接创建一个我的类型的变量调用吃这个方法实现对面这个类类型
的一个变量的操作
牛.吃(草); //直接创建一个我的类型的变量调用吃这个方法实现对面这个类类型
的一个变量的操作
牛.反刍(); //牛类类型的变量实现了一个空的方法反刍。
上面的例子基本上就实现了面向对象编程的一个概述,其中牛和草之间只有吃与被吃的关系,他们之间的只是通过一个实例变量来实现练习,这样就把牛和草的其他信息都封装起来了。