1.从面向对象说起
~~~~~~ 变化是代码复用的天敌,面向对象的设计语言的优势就是抵御变化!这里的所谓抵御变化,不是说采用面向对象的设计语言,就没有变化,而是将变化的范围降到最小。
~~~~~~ 之前我们所认识的面向对象的语言,具有封装、继承和多态三大特性,但这是面向对象的底层思维;
~~~~~~ 从抽象思维认识面向对象,它首先要能隔离变化:从宏观的角度来看,面向对象的语言更能适应软件带来的变化,将这种变化的影响降到最低,
~~~~~~ 其次面向对象要求各个类之间各司其职:从微观的角度来看,面向对象更强调各个类各个承担的责任,各个类之间各司其职,变换导致的新增类型不应该影响原有的类,一般使用C++多态机制实现这种“各司其职”,接口一致,但是实现不一。
2.对象究竟是什么?
~~~~~~ 从语言的角度来看,对象封装了代码和数据;
~~~~~~ 从规格的角度来看,对象是一系列的可被使用的公共接口;
~~~~~~ 从概念的角度来看,对象是某种拥有责任的抽象
3.面向对象的设计原则(8个)
~~~~~~ 1.依赖倒置原则
~~~~~~~~~~ 高层模块不应该依赖于低层模块,二者都应该依赖于抽象;
~~~~~~~~~~ 抽象不应该依赖于实现细节,而实现细节应该依赖于抽象;
这里的高层模块可以理解为父类,低层模块可以理解为子类,抽象可以理解为抽象类,
实现细节可以理解为具体的虚函数功能实现。这句话就是说父类不应该依赖子类,它们都要依赖抽象类,
抽象类中不要有具体的函数实现,而具体的虚函数实现要依赖于抽象类所谓的依赖倒置是指在编写代码时,一般的编写规则是抽象在最上,然后父类,最下面是子类。
但是设计模式的依赖关系是倒置的,下面的代码需要依赖上面的,这就是依赖倒置原则。
~~~~~~ 2.开放封闭原则
~~~~~~~~~~ 对拓展开放,对修改封闭;
~~~~~~~~~~ 类的模块应该是可拓展的,但是不可修改;
当需求变化时,首先想到的不应该是修改源代码,修改的成本太高,并且大型代码不能轻易修改,
而是在原来代码不变的基础上,增加一些代码,以实现某些需求。
当然可拓展性需要提前在做好规划,比如在抽象类中提前留好拓展接口
~~~~~~ 3.单一职责原则
~~~~~~~~~~ 相同的责任不要分散到不同的类中;
~~~~~~~~~~ 避免一个类承担不同的责任
单一职责的好处是:减少耦合性,提高复用性
~~~~~~ 4.替换原则
~~~~~~~~~~ 子类能够替换它的父类
为什么要强调子类能够替换父类呢?如果子类能够替换父类,说明父子类之间的强关系,
至少父类的实现在子类中都有
~~~~~~ 5.接口隔离原则
~~~~~~~~~~ 不要给客户程序提供它们用不到的方法,接口应该尽量小而完备。
客户程序用不到的类中方法,就不要public出去,
如果只是自己类中使用,就private;如果只是子类中使用,就protected;
真正有必要的情况下,即客户程序真的需要这个方法,才去public
~~~~~~ 6.优先使用对象组合而不是类继承
继承某种程度上会破坏封装性,父类子类间的耦合性高,而对象组合不会出现这种问题。
~~~~~~ 7.封装变化点
封装的最高境界是封装变化点,一端变化,一端不变化
~~~~~~ 8.针对接口编程,不针对实现编程