知识总结
- 尽可能的将程序耦合度降到最低
- 能复用则复用
- 能小则小
- 能独立就独立
- 能接口就接口,能抽象类就抽象类
- 能增加就不更改
开闭原则
定义
软件中的实体(类 模块 函数)应当对于拓展是开放的,对修改是封闭的 Software entities should be open for extension,but closed for modification
含义
当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。
作用
- 对软件测试的影响 (软件遵守开闭原则的话,软件测试时只需要对扩展的代码进行测试就可以了,因为原有的代码仍然能够正常运行)
- 可以提高代码的可复用性 (粒度越小,被复用的可能性就越大;在面向对象的程序设计中,根据原子和抽象编程可以提高代码的可复用性)
- 可以提高软件的可维护性 (遵守开闭原则的软件,其稳定性高和延续性强,从而易于扩展和维护)
实现方法
可以通过接口或者抽象类为实体定义一个相对稳定的抽象层,而将相同的可变因素封装在相同的具体实现类中。
因为抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定。而软件中易变的细节可以从抽象派生来的实现类来进行扩展,当软件需要发生变化时,只需要根据需求重新派生一个实现类来扩展就可以了。
里氏替换原则
是对开闭原则的补充
子类可以扩展父类的功能,但不能改变父类原有的功能。
子类继承父类时,除添加新的方法完成新增功能外,尽量不要重写父类的方法。
作用
- 里氏替换原则是实现开闭原则的重要方式之一。
- 它克服了继承中重写父类造成的可复用性变差的缺点。
- 它是动作正确性的保证。即类的扩展不会给原来的系统引起错误,降低了代码出错的可能性。
依赖倒置原则
定义
高层模块不应该依赖底层模块 , 两者都应该依赖于其抽象层 ; 抽象不应该依赖于细节 , 细节应该依赖抽
High level modules shouldnot depend upon low level modules.Both should depend upon abstractions.Abstractions should not depend upon details. Details should depend upon abstractions
其核心思想是:要面向接口编程,不要面向实现编程。
作用
依赖倒置原则是实现开闭原则的重要途径之一,
- 降低了客户与实现模块之间的耦合。
- 可以提高系统的稳定性
- 可以减少并行开发引起的风险
- 可以提高代码的可读性和可维护性
实现方法
- 每个类尽量提供接口或抽象类 或者两者都具备
- 变量的声明尽量是接口或者是抽象类
- 任何类都不应该从具体类派生
- 使用继承时尽量遵循里氏替换原则
单一职责原则
定义
单一职责原则规定一个类应该有且仅有一个引起它变化的原因,否则类应该被拆分
There should never be more than one reason for a class to change
作用
- 一个职责的变化可能会削弱或者抑制这个类实现其他职责的能力
- 当用到该对象的一个职责的时候,不得不将其他不需要的职责全都包含进来,从而造成冗余代码
- 降低类的复杂度 (一个类只负责一项职责 , 其逻辑肯定比负责多项职责简单的多)
- 提高类的可读性 (复杂度降低可读性会提高)
- 提高系统的可维护性 (可读性提高自然就容易维护了)
- 变更引起的风险降低
实现方法
需要设计人员发现类的不同职责并将其分离,再封装到不同的类或模块中。
需要经验和总结分析
接口隔离原则
定义
客户端不应该被迫依赖于它不使用的方法 或者 一个类对另一个类的依赖应该建立在最小的接口上
Clients should not be forced to depend on methods they do not use OR The dependency of one class to another one should depend on the smallest possible interface
单一职责 与 接口隔离 都是为了提高类的内聚性 降低他们之间的耦合性 体现了封装的思想
作用
- 将庞大的接口分解为多个粒度小的接口 , 可以预防外来变更的扩散 , 提高系统的灵活性和可维护性
- 接口隔离提高了系统的内聚性 , 减少了对外交互 , 降低了系统的耦合性 , 保证系统的稳定性
- 使用多个专门的接口还能够体现对象的层次 , 因为可以通过接口的继承 , 实现对接口的定义
其他原则方法
迪米特法则
定义
只与你的朋友交谈 , 不跟陌生人说话
Talk only to your immediate friends and not to strangers
含义
如果两个实体无需直接通讯 , 那么就不应该发生直接的相互调用 , 可以通过第三方转发该调用
其目的 降低类之间的耦合度 , 提高模块的相互独立性
实现方法
- 在类的划分上 , 应该创建弱耦合的类 . 类与类之间的耦合越弱 , 越有利于实现可服用的目标.
- 尽量降低类成员的访问权限
- 优先考虑将一个类设置成不变类
- 将引用其对象的次数降到最低
- 不暴露类的属性成员 , 应该提供相应的属性访问器
- 谨慎使用序列化功能(Serializable)(不懂)
合成复用原则
在软件复用时 , 要尽量先使用组合或者聚合等关联关系来实现 , 其次才考虑使用继承关系
如果要使用继承关系 , 则必须严格遵循里氏替换原则