- 单一职责原则。职责单一,只负责一项职责。意味着不会存在多于一个导致类变更的原因。
问题:若一个类负责A、B两个职责,则A职责变动,修改后可能使正常的B职责发生故障。
- 里氏替换原则。程序内,任何基类出现的地方,用子类替换,程序的行为不变。
问题:有一个功能P1,由A类完成。先需要对功能P1进行扩展成为P,新功能P由原功能P1和新功能P2构成。P2由A的子类A'完成。子类A'可能在完成P2功能的同时导致原有功能P1发生故障。
解决:当使用继承时,遵循里氏替换原则。A'添加新增功能外,尽量不要重写、重载父类方法(一不小心,就误调用)。
方法:
1. 子类可实现父类抽象方法,但不能重写父类非抽象方法。
2. 子类可增加自己特有方法。
3. 重载父类方法时,方法的形参要比父类的更宽松。
4. 实现父类抽象方法时,方法的返回值要比父类严格。
- 依赖倒置原则。高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节;细节应该依赖抽象。
问题:类A直接依赖类B,现在要改成依赖类C,则必须通过修改代码来实现,这样会带来不必要的风险。
解决:新增接口I,类A依赖接口I。类B、C实现接口I。这样会大大降低修改类A的几率。
- 接口隔离原则。定义:客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。
问题:类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法。
方法:
1. 接口尽量小,但也要有限度。过小,接口会过多,使设计复杂。
2. 为依赖接口的类做定制服务,只暴露类需要的方法,其他隐藏。
- 迪米特法则。一个对象应该对其他对象保持最少的了解。
问题由来:类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大。
解决方案:尽量降低类与类之间的耦合。
朋友关系:两个对象之间有耦合关系
直接朋友:出现成员变量、方法参数、方法返回值中的类
间接朋友:出现在局部变量中的类
结论:陌生的类最好不要作为局部变量的形式出现在类的内部。
- 开闭原则 。一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。
问题由来:在软件的生命周期内,因为变化、升级和维护等原因需要对软件原有代码进行修改时,可能会给旧代码中引入错误,也可能会使我们不得不对整个功能进行重构,并且需要原有代码经过重新测试。
解决方案:当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。
如何才算遵循开闭原则:遵循设计模式前面5大原则,以及使用23种设计模式。