1、开闭原则
定义:系统、模块、类、方法对扩展开发,对修改关闭
2、单一职责原则
定义:系统、模块、类、方法只负责自己的事情,而不是变成万能的
3、依赖倒置原则
定义:高层模块不应该依赖低层模块,二者都应该依赖其抽象,抽象不应该依赖细节,细节应该依赖抽象,面向接口编程。依赖抽象,不依赖具体,如果一个对象依赖另一个对象的具体实现类,那就是强耦合,如果依赖的是另一对象的接口,就是松耦合。
4、接口隔离原则
定义:客户端使用一个类时,不要将这个类转换成它的最顶级接口,而是转换成客户端需要使用的那个接口类型,这可以将不同父接口方法隔离开来,这也是面向对象里的多态。
interface A{}
interface B extends A{}
interface C extends B{}
class a exmplements C{
}
class client {
public void fun(){
//尽量不转换为总接口类型
// A a = new a();
B a = new a();
//需要使用哪个接口方法时,转换成哪个接口
C a = new a();
}
}
5、里氏替换
一、 定义:
1、里氏替换原则通俗的来讲就是:子类可以扩展父类的功能,但不能改变父类原有的功能。
2、里氏代换原则告诉我们,在软件中将一个基类对象替换成它的子类对象,程序将不会产生任何错误和异常,反过来则不成立,如果一个软件实体使用的是一个子类对象的话,那么它不一定能够使用基类对象。
3、里氏代换原则是实现开闭原则的重要方式之一,由于使用基类对象的地方都可以使用子类对象,因此在程序中尽量使用基类类型来对对象进行定义,而在运行时再确定其子类类型,用子类对象来替换父类对象。
二、里氏替换原则包含的含义
1、子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法
在我们做系统设计时,经常会设计接口或抽象类,然后由子类来实现抽象方法,这里使用的其实就是里氏替换原则。子类可以实现父类的抽象方法很好理解,事实上,子类也必须完全实现父类的抽象方法,哪怕写一个空方法,否则会编译报错。
里氏替换原则的关键点在于不能覆盖父类的非抽象方法。父类中凡是已经实现好的方法,实际上是在设定一系列的规范和契约,虽然它不强制要求所有的子类必须遵从这些规范,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破坏。而里氏替换原则就是表达了这一层含义。
2、子类中可以增加自己特有的方法
在继承父类属性和方法的同时,每个子类也都可以有自己的个性,在父类的基础上扩展自己的功能。前面其实已经提到,当功能扩展时,子类尽量不要重写父类的方法,而是另写一个方法
3、当子类覆盖或实现父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松
简而言之:里氏替换原则是,继承父类时不要重写父类方法,而是扩展或重载
6、迪米特原则
定义:一个对象应该对其他对象保持最少的了解,又叫最少知道原则,尽量降低类与类之间的耦合。不应该持有不属于它的引用。
7、组合复用原则
定义:尽量使用对象组合、聚合而不是通过继承关系达到软件复用的目的。能用组合(构造器传入引用)就用组合,尽量不要用继承,因为组合/聚合关系是运行时动态行为,而继承是编译期行为,组合聚合比继承更加灵活。
使用组合/聚合实现复用有如下好处:
新对象访问成分对象的唯一方法是通过成分对象的接口。
这种复用是黑箱复用,因为成分对象的内部细节是新对象所看不见的。
这种复用所需的依赖较少。
每一个新的类可以将焦点集中在一个任务上。
这种复用可以在运行时间内动态进行,作为整体的新对象可以动态地引用与部分对象类型相同的对象。也就是说,组合/聚合是动态行为,即运行时行为。可以通过使用组合/聚合的方式在设计上获得更高的灵活性。
组合/聚合是黑箱复用
继承是白箱复用
组合聚合是has-a的关系
继承是is-a的关系