Java设计中的七大原则
一、 “开-闭”原则
????? 就是在软件设计中做到对扩展开放,而修改是关闭;在现实开发中一套庞大系统里类之间存在千丝万缕的关系,如果在后期、或者维护时期对原有的代码进行修改会出现难以预料的后果,这也是提倡对修改封闭的原因之一。但是又要对系统的功能增加和改善保留可扩展的余地,从而就会提出对扩展开放的思想。
????? 如何做到这点呢?关键在于对问题域中的对象进行抽象化,在java语言中可以给出一个或多个java抽象类或java接口,规定出所有具体类所具有的方法的特征来作为设计的抽象层。在任何扩展情况下抽象都用不着改变,这就使得系统的抽象层不需要修改,而去扩展新的实现。从而就满足了“开-闭”原则。
二、 里氏代换原则
????? 当子类可以替换其父类,并且功能不会受到影响时父类才真正被重用,而子类才能够在父类的基础上增加新的行为。需指出的是反过来的代换是不成立。
????? 里氏代换要求凡是父类型使用到的地方,子类型一定适用,因此子类必须具备父类型的全部接口
三、 依赖倒转原则
????? 抽象不应当依赖于细节,细节应当依赖于抽象;针对接口编程,不要针对实现编程。
????? 在传统的过程性系统的设计办法倾向于使高层次的模块依赖于低层次的模块;抽象层依赖于具体实现层,将这错误的依赖关系推翻就是依赖倒转的由来。
抽象层依赖于具体实现层的含义是?抽象层是包含应用系统的商务逻辑和宏观的、对整个系统起重要的战略性决定的,是必然性的体现;而具体实现层含有一些次要的与实现有关的算法和逻辑。具体层的代码是会经常有变动的,不能避免出现错误。所以,这种抽象依赖于具体实现的是显然不对的。
???? (一) 在面向对象的系统里,两类之间可以发生三种不同的耦合关系:
????????????? 1. 零耦合:也就是说没有耦合关系
????????????? 2. 具体耦合:是由具体类之间直接引用所发生的关系
????????????? 3. 抽象耦合:是一个具体类与一个抽象类之间引用关系,这种存在着最大的灵活性
???? (二) 针对接口编程,不要针对实现编程
?????????????? 接口编程的意思是说应当使用java接口和java抽象类进行变量的类型声明、参数类型声明、方法的返回类型声明,以及数据类型的转换等。
??????? 实现编程的意思是说不应当使用java的具体实现类进行变量类型声明、参数类型声明、方法的返回类型声明等等。
??????? 倒转依赖关系强调一个系统内的实体之间关系的灵活性。实现依赖倒转原则的关键是以抽象方式的耦合。抽象耦合关系总要涉及到具体类从抽象类继承,并且要保证在任何引用到基类的地方都可以改换成其子类。因此,里氏代换原则是依赖倒转原则的基础。
四、 接口隔离原则
?????? 接口:一种是指有严格定义的Interface结构,另一种就是一个类型所具有的方法特征的集合,但也是一种逻辑上的抽象。
?????? 接口的定义也会带来类型的划分;一个接口相当于剧本中的一种角色,而角色在一个舞台上由哪一个演员来演则相当于接口的实现,因此一个接口应当简单的代表一个角色,而不是多个角色。
?????? 将没有关系的接口合并在一起,形成一个臃肿的大接口,过于臃肿的接口是对接口的污染。准确而恰当的划分角色以及角色所对应的接口,是面向对象的设计的一个重要组成部分
五、 合成/聚合复用原则又称“合成复用原则”
??????? 在一个新的对象里面使用一些已有的对象,使之成为新对象的一部分;新的对象通过向这些对象的委派达到复用已有功能的目的。简而言之,就是要尽量使用组合/聚合,少用继承。
聚合与组合的区别:
聚合是用来表示“拥有”关系或者整体与部分的关系。
组合则是表示一种强得多的“拥有”关系,在组合里,部分与整体的生命周期是一样的。一个组合的新的对象完全拥有对其组成部分的支配权,包括它们的创建和湮灭等。一个组合关系中的成分对象是不能与另一个组合关系共享的。一个组成部分在同一个时间内只能属于一个组合关系。
复用的基本方式有两种:1. 组合/聚合 2. 继承
两者区别:
组合/聚合是将已有的对象纳入到新对象中,使之成为新对象的一部分,该方式的好处有:
???? 1. 新对象存取成分对象的惟一方法是通过成分对象的接口。
???? 2. 这种复用是黑箱复用,因为成分对象的内部实现细节是新对象所看不见的。
???? 3. 这种复用支持包装。
???? 4. 这种复用所需的依赖较少。
???? 5. 每个新的类可以将焦点集中在一个任务上。
???? 6. 这种复用可以在运行时间内动态进行,新对象可以动态引用与成分对象类型相同的对象
缺点:通过使用这种方式复用建造的系统会有较多的对象需要管理。
继承是面向对象特有的复用工具,而且也最容易被滥用。继承复用通过扩展一个已有对象的实现来得到新的功能。
优点:
???? 1. 较为容易,因为父类的大部分功能都可以通过继承关系自动进入子类。
???? 2. 修改或扩展继承而来的实现较为容易。
缺点:
????? 1. 破坏包装,因为继承将父为的实现细节暴露给子类。因此,这种复用又叫“白箱”复用。
????? 2. 父类的实现发生变化,其子类也不得不随之发生改变。所以,修改父类就会形成链锁反映。
????? 3. 从父类继承而来的实现是静态的,不可能在运行时间内发生改变,因此也没有足够的灵活性。
未完,待续......
?