一 . 起因
代码的复用是我们追求的境界,因为复用我们可以减轻我们工作量,这就是我们追求设计最初的目的.
在面向对象的设计中,代码的复用最常见的方式有两种:
[1]继承的方式: 由于继承,子类就拥有了父类的方法,那么我们就没必要重新复制一遍父类的实现方式,这是一种复用方式.
但是,继承会带来一些列的问题.因为一旦继承,我们可能就拥有了父类中的一些其它方法,往往这些方法可能子类不该拥有,这个时候可以说 明是继承使用不当.
[2]组合的方式: 简单说,就是一个对象拥有一些方法,我们想使用这些方法,只需要在我们的类中持有一个该对象的引用,那么我们自然就拥有了使用这个方法的权利,那么代码自然就可以服用了.
组合的方式应该优先于继承的方式.
代码如何复用?
前提是封装.
封装我们一般认为是一些列功能的组合,构成一个更强大的功能的形式.[另外数据和数据的方式也是封装].
封装的粒度问题?
那么我们封装到什么程度是好的呢?---权衡的条件就是责任明确[单一责任原则].
单一责任就是说我们封装好的类,一定是功能关联的方法,也就是说一个类只应该明确完成一定量的事情.
越小的类以后被复用的可能就越大.
继承的出现:
现在我们拥有了一系列小的类,我们出现了基本的继承复用需求.
如继承是创建新类的一种快捷的方式,我们只要继承就可以获得父类的功能.另外我们还可以定义一些额外的方法.
那么继承是否合理的判断条件是什么?
我们总不能因为需要一个类的某些方法就继承吧?
原则就是里氏替换原则.
子类型必须能够替换父类型.
比如: public void 射击(枪);
我们实现了枪的继承结构:
我们的方法中,使用父类枪做为参数,那么我们传递子类型也应该是合理的.
如果不合理,那么就是继承有问题.
多态的出现: 上面我们用到了多态,子类在运行时可以明确调用自己的方法.
那么现在我们创建了一个新类,激光枪,那么激光枪也应该适合上面的射击方法.
多态给我们了一个良好的扩展性,这里的扩展性是说,我们可以增加新类,但是对于旧类我们不应该再次修改.
[旧类被其它地方使用着,你修改旧类也就意味着你在挑战自己,毕竟你无法知道你的修改到底是否正确.在没出问题之前,你不能说你的修改没错,但出现问题,就说明你修改错误了.]
这就是开闭原则----对扩展开放,对修改关闭.
[这也是在保护自己的一种方式].---呵呵.
怎么能实现开闭原则-----我们就需要使用接口隔离原则,也就是说我们应该面向接口编程.
比如上面的方法,我们的参数是一个父类枪类型,如果我们定义的时候定义的是一个Ak47类型,那么这个方法需要激光枪的时候就需要重写一个方法了 .
这也就是面向抽象编程.
其实还有很多原则,但是从根本上讲都是一样的,怎么做能更好的复用代码,我们就怎么去做.
总结一下:
[1]首先我们应该封装代码,[不封装就不能够复用]
[2]复用的方式: (1)继承 (2)组合 优先组合
[3]面向接口编程
那么你一定会使用多态 ,那么你的程序的扩展性一定会更好.
重构:
代码是修改出来的,没人能一次性写好代码的.
重构就是实现这些原则和设计思想的过程,也是你理解代码的过程.
重构的结果和过程,就是一系列的设计模式的雏形.
设计模式: 一些良好代码设计的范本,和解决思路.
也就是说:
(1)问题出现
(2)大神解决问题
(3)大神总结了这种问题应该怎么解决
---于是出现了设计模式.[符合设计原则的]
我们怎么做?
其实对于我自己来讲,能真正使用模式的机会不多,但是
写良好代码的机会却很多.这也就是说,我们可以参照这些设计模式的思想写出一些更能复用的代码.
这也就是学习设计模式最根本的原因.
[1]你发现自己的代码很烂
[2]找到一些好的代码实现[很多的模式,良好的复用,非常容易让人理解]
[3]自己模仿写写就好了
程序员洁癖和纯洁审美养成的过程:
所有的代码都很烂,我能让它变的更美好.