可维护(使维护工作容易、准确、安全、经济的进行)和可复用是面向对象要解决的核心问题
开-闭原则
在支持可维护的同时提高系统的可复用性
软件的维护就是软件的再生
导致一个软件设计的可维护性较低的原因:过于僵硬、过于脆弱、复用率底、黏读过高。
设计目标:可扩展性(新的性能可以很容易的加入其中)、灵活性(可以平稳修改原来代码)、可以插入(那一个新的去换原来的一个旧的)。
如何做到可以扩展性、灵活性、可插入性呢?提高软件的可维护性和复用性
系统的复用性:代码复用、算法复用、数据结构复用。数据的抽象化(概念复用)、继承(定义复用)、多态(实现复用)。抽象话和封装可以提高系统的可以
可维护性。抽象层次的稳定是复用的重点,如果抽象层次的模块相对独立于具体层次的模块的话,那么具体层次的变化就不会影响到抽象层次的结构。
系统的可扩展性能:由开闭原则、里氏代换原则、依赖倒转原则和组合/聚合复用原则所保证的。
系统的灵活性:有开闭原则、迪米特法则、接口隔离原则所保证。
系统的可插入性:由开闭原则、里氏代换原则、依赖倒转原则和组合/聚合复用原则所保证的。
设计原则:
开闭(ocp):对扩展开发,对修改关闭。应该在可以不修改源代码的情况下,改变这个模块的行为。(不允许改变的是抽象层,允许扩展的是实现层)
通过提供新的行为,以满足对软件的新需求。使变化中的软件系统有一定的适应性和灵活性
已有的软件模块,特别是最重要的抽象层模块,不能再修改,这就是变化中的软件系统有一定的 稳定性和延续性
对可变性封装(evp):继承应当被看做封装变化的方法,而不应当被认为是中一般对象生成特殊对象的方法。一种可变性不应当与另一种可变性混在一起
里氏代换原则
任何基类可以出现的地方,子类一定可以出现
依赖倒转
要依赖与抽象,不要依赖与实现
接口隔离
应当为客户端提供尽可能小的单独的接口,而不要提供打的总接口
组合/聚合复用原则
要尽量使用组合/聚合,而不是继承关系达到复用的目的
迪米特法则
一个软件实体应当与尽可能少的其他实体发生相互作用
这些原则都是复用的原则,可以提高系统的复用性,同时提高系统的可维护性
将条件转移语句改写成为多态性。
接口是可插入性的保证
应当使用java接口和抽象java类而不是具体类进行变量的类型声明、参数的类型声明、方法的返回类型声明、以及数据类型的转换等。
接口:
单方法接口
标识接口(一般使用在工具类中)
常量接口(用java接口来声明一些常量,然后由实现这个接口的类使用这些常量)。不建议使用
抽象类:
有构造方法,但不能被实例化,一个抽象类的构造方法是被子类调用的。从而使抽象类的所有子类都有一个共同的实现,而不同的子类在此基础上可以有自己的实现。
抽象类的用:天生就是用来被继承的,反过来说具体类不是用来继承的(只要有可能,不要从具体类继承)。所有的继承都是从抽象类开始的,所有的具体类都没有子类。
里氏代换原则。注:模板方法模式根本就是关于继承的模式。
在一个从抽象类到多个具体类的继承关系中,共同的代码应尽量移动到抽象类里,共同代码想登记结构的上方移动。与代码的移动方向相反,数据的移动方向是从抽象类到具体
类。
继承:1、子类是超类的一个特殊种类,而不是超类的一个角色,也就是要区分has-A与is-A,has-A关系应当使用聚合关系描述,而只有is-A关系才符合继承关系。
2、永远不会出现需要蒋子类换成另外一个类的子类的情况
3、子类具有扩展超类的责任,而不是置换或注销超类的责任。
4、只有在分类学角度上有意义时才可以继承,不用从工具类继承。
里氏代换原则是可否使用继承的准绳(子类始终可以被当作父类来使用)。
代码重构中里氏代换解决方法:1、创建一个新类C,作为具体类A和B的超类,将A和B的共同行为移到C中,从而解决A和B行为不一致的问题
2、用委托代替继承
依赖倒转:依赖倒转原则讲的是,要依赖于抽象,不要依赖于具体。它强调的是一个系统内实体之间关系的灵活性。是遵守开闭原则的重要途径。
针对接口编程的意思就是说,应当使用java接口和抽象java类进行变量的类型声明、参量的类型声明、方法的返回类型声明、以及数据类型的转换等。要保证做到这一点一个
一个具体java类应当只实现java接口和抽象java类中声明过的方法,而不应该给出多余的方法。
接口隔离(ISP):使用多个专门的接口比使用单一的总接口好。(一个类所提供的方法的集合,是一种逻辑上存在的概念。接口的划分直接带来类型的划分。一个接口代表一种 角色,它的实现就相当于演员。)在接口设计中要防止:接口污染,将角色区分清楚是系统设计的一个重要方面。要用定制服务原则(迪米特法则要求任何一个软件实体,除非绝对需要,不然不要与外界通信,即使必须进行通信也尽量限制通信的广度和深度,定制服务原则拒绝向客户提供不需要的行为)
合成聚合原则:尽量使用组合聚合,少使用继承。在一个新对象里面使用一些已有对象,使之成为新对象的一部分,新对象通过向这些对象的委派达到复用已有功能的目的。
迪米特法则(类之间的关系法则):最少知原则,一个对象对其他对象应该尽可能的少了解。(不要和陌生人说话,只与你直接的朋友通信。如果两个类不必直接通信,那么这两个类就不应该直接发生作用,如果其中的一个类需要调用另一个类的方法,可以通过第三者转发这个调用。)调用转发,使某人知道有朋友,而隐藏陌生人的存在,使某人任务他调用的这个方法是朋友的方法而不是陌生人的方法
朋友的定义:当前对象、以参量形式传入到当前对象的方法中的对象、当前对象的实例变量直接引用的对象、当前对象锁创建的对象、当前对象的实例如果是一个集合,那么集合中的元素也是。