1.开闭原则(Open Close Principle)
对扩展开放,对修改关闭;想要达到这种效果,需要使用接口和抽象类.
开闭原则对扩展开放,对修改关闭,并不意味着不做任何修改,低层模块的变更,必然要有高层模块进行耦合,否则就是一个孤立无意义的代码片段.
2.里氏代换原则(Liskov Substitution Principle)
所有引用基类(父类)的地方必须能够透明的使用其子类的对象;(通俗定义)
里氏代换原则告诉我们:在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是
一个子类对象的话,那么她不一定能够使用基类对象.例:
我喜欢动物,那我肯定喜欢狗;但是我喜欢狗,并不能断定我喜欢动物;因为我不喜欢猫,虽然它也是动物.
因此 程序中尽量使用基类类型来定义对象,而在运行时在确定其子类类型,用子类来代替父类对象;如 Animal dog = new Dog();
- 子类必须完全实现父类的方法;
在类中调用其他类时务必要使用父类或者接口,如果不能使用父类或者接口,则说明类的设计已经违背了LSP原则(里氏代换原则) - 子类可以有自己的个性
向下转型(downcast)是不安全的,就是有子类出现的地方父类不一定就可以出现 覆盖或者实现父类的方法时输入参数可以被放大
覆写或实现父类的方法时输出结果可以被缩小
3.依赖倒转原则(dependence Inversion principle)
High level modules should not depend up on low level modules;
Both should depend on abstractions.
Abastractions should not depend up on details.
Details should depend up on abstractions.
高层模块不应该依赖底层模块,两者都应该依赖其抽象;
抽象不应该依赖细节;
细节应该依赖抽象;
开闭原则的基础,具体内容:对接口编程,依赖于抽象而不依赖具体. 核心思想是 面向接口编程.
高层模块不应该依赖底层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象.
例:妈妈给孩子讲故事,给她一本书就可以讲故事,如果妈妈依赖的书,则后期如果加入报纸,杂志,妈妈则无法读取其内容;
这样就需要修改成 妈妈依赖读物的接口,书 报纸和杂志等实现读物的接口,妈妈直接调用读物的实现类.
依赖倒置原则基于这样一个事实:相对于细节的多变性,抽象的东西要稳定的多.以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多.
在java中,抽象指的是接口或者抽象类,细节就是具体的实现类,使用接口或者抽象类的目的是制定好规范和契约,而不去涉及任何具体的操作,把展现细节的
任务交给他们的实现类去完成
4.接口隔离原则(Interface Segregation Principle)
使用多个隔离的接口,比使用单个接口要好.可以方便升级和维护.降低依赖,降低耦合.
衡量规则:
4.1 一个接口只服务于一个子模块或者业务逻辑
4.2 通过业务逻辑压缩接口中的public方法;
4.3 已经被污染的接口,尽量去修改;若变更的风险较大,则采用适配器模式进行转化处理;
4.4 了解环境,拒绝盲从;
5.迪米特法则(最少知道原则)(Demeter Principle)
一个实体应该尽量少的与其他实体之间发生相互作用,使得系统功能模块相对独立.
迪米特法则的核心观念就是类间解耦,弱耦合,只有弱耦合了以后,类的复用率才可以提高.其要求的结果
就是产生了大量的中转或者跳转类,导致系统的复杂性提高,同时也为维护带来了难度.所以,在采用迪米特法则时需要反复权衡,既要做到结构清晰,又要做到高内聚低耦合.
6.合成复用原则(Composite Reuse Principle)
尽量使用 合成/聚合的方式,而不是使用继承.