开闭原则
定义:一个软件实体应当对扩展开放,对修改关闭。即软件实体应尽量在不修改原有代码的情况下进行扩展。
这是终极追求, 其余五个设计原则就是为了最终达到开闭原则。
单一职责原则
定义:应该有且只有一个原因引起类的变更。换句话说就是一个接口只做一件事,即一个职责一个接口。侧重点业务职责。
分类:接口级别、方法级别。
接口隔离原则
定义: 建立单一接口,不要建立臃肿庞大的接口。即接口尽量细化,同时接口中的方法尽量少。
接口隔离原则是对接口定义的规范。含义主要包含以下4点。
- 接口尽量小。根据具体业务把一个接口按照接口隔离原则细化成更多的接口。但是在此基础之上必须不能违背单一职责原则。
- 接口要高内聚。高内聚的意思就是提高接口和类处理能力,减少对外的交互。接口是对外的承诺,因此设计时应该尽量少公布接口中的public方法,承诺越少系统开发越有利且变更风险就越少。
- 定制服务。定制服务就是单独为一个个体提供服务,即只提供访问者需要的方法。举一个图书管理系统的例子,有一个查询接口BookSearch,包括如下方法:searchById,searchByBookName,searchByCategory,complexSearch,其中前三个方法是提供给学生使用的,后一个方法是提供给管理员使用的,学生对这个方法的访问是有限制的,调用不会返回任何值。当这四个方法全部公布出去之后,学生对此方法的访问即使不返回任何值也会使服务器性能下降。因此合理的设计应该是拆分这个接口为两个接口:SimpleSearch和AdminSearch。SimpleSearch接口提供searchById,searchByBookName,searchByCategory方法,AdminSearch接口提供complexSearch方法,此时学生实现SimpleSearch接口即可,管理员同时实现SimpleSearch和AdminSearch两个接口
- 接口设计是有限度的。接口设计越小越好,但是结构同时会变得复杂,维护也变得难了。因此就要把握住这个度。
里氏替换原则
定义:所有引用基类(父类)的地方必须能透明地使用其子类的对象。
通俗的理解:只要父类出现的地方子类就可以出现,且替换成子类也不会出现任何错误或者异常。(但是反过来,有子类出现的地方,父类不一定可以适用)
里氏替换原则是为继承定义了规范
- 子类必须完全实现父类的方法。
- 子类可以有自己的个性。
- 覆盖或者实现父类的方法时输入参数可以被放大。
依赖倒置原则
定义:抽象不应该依赖于细节,细节应当依赖于抽象。换言之,要针对接口编程,而不是针对实现编程。
精简的定义就是面向接口编程。在Java语言中的表现就是为以下的三点
- 模块间的依赖关系通过接口和抽象类产生,实体类之间不直接发生依赖关系。
- 接口和抽象类不依赖于实现类。
- 实现类依赖接口或者抽象类。
典型实现: ssh的分层思想,开发中上层依赖下层的接口而非具体实现,sprig容器管理bean并帮我们注入对下层的依赖对象。
迪米特法则
定义:一个软件实体应当尽可能少地与其他实体发生相互作用。
典型例子: 门面模式
补充:单一职责要求类和接口,或者方法的职责单一,侧重点在职责,这是根据业务逻辑进行划分的。而接口隔离原则要接口中的方法尽量少。比如,一个接口或者一个中有十个方法,不同的方法做不同的事情,但是这个接口总体就是处理一件事情,然后具体细分成了10个方法。不同的模块根据不同的权限进行访问,这是符单一职责原则的。但是按照接口隔离的原则是要求接口接口中的方法尽量少,落实到这个实例就是要求尽量多几个专门的接口供不同的模块使用,而不是只有一个臃肿的接口,依据权限去限制不同模块可以访问的方法。