Java项目中常用的的五大设计原则
今天我们一起来聊聊关于设计原则相关的知识点。
SOLID五大原则是什么
SRP 单一责任原则
单一责任原则,从名字上我们就能比较好的去理解它。这项原则主张一个对象只专注于单个方面的逻辑,强调了职责的专一性。
举个例子:
学生管理系统中,我们需要提交一些学生的基本资料,那么学生信息相关的程序都交给了StudentService负责,如果我们要实现一个保存教师基本资料的功能就应该新建一个TeacherService去处理,而不应该写在StudentService当中。
OCP开放封闭原则
这项原则从我个人的角度去理解,它更加强调的是对于扩展的开放性,例如当我们需要调整某些实现逻辑的时候,尽量不要直接改动到原有的实现点。
但是这里面有几个点容易被人们误解:
第一点
开放封闭原则虽然强调的是不要随意改动代原先代码到逻辑结构,但是并没有要求一定不能对代码进行改动!
第二点
同样是代码改动,如果我们可以从功能,模块的角度去看,实际上代码的改动更多地可以被认作为是一种“扩展”。
关于如何做到开放封闭原则,下文我会专门用一个案例来进行介绍。
LSP里氏替换原则
里氏替换原则强调的是不能破坏一个原有类设计的原始设计体系。强调了子类可以对父类程序进行继承。但是有几个点需要注意下:
如果父类定义的规则最好是最基础,必须遵守的法则。如果子类继承了父类之后,在某个方法的实现上违背了初衷,那么这样的设计就是违背了里氏替换法则。
例如:
父类的设计是希望实现商品库存扣减的功能,但是子类的实现却是实现了库存+1的功能,这就很明显是牛头不对马嘴了。
子类不要违背父类对于入参,出参,异常方面的约定。例如:父类对于异常的抛出指定的是 NullPointException ,但是子类却在实现的时候声明了会出 illegalArgumentException,那么此时就需要注意到设计已经违背了LSP原则。
同样,具体的案例我在下文会列举出来和大家进行代码分享。
ISP接口隔离原则
理解“接口隔离原则”的重点是理解其中的“接口”二字。
这里有三种不同的理解。如果把“接口”理解为一组接口集合,可以是某个微服务的接口,也可以是某个类库的接口等。
如果部分接口只被部分调用者使用,我们就需要将这部分接口隔离出来,单独给这部分调用者使用,而不强迫其他调用者也依赖这部分不会被用到的接口。
DIP依赖倒置原则
比较经典的例子,例如说Spring框架的IOC控制反转,将bean的管理交给了Spring容器去托管。依赖注入则是指不通过明确的new对象的方式来在类中创建类,而是提前将类创建好,然后通过构造函数,setter函数等方式将对应的类注入到所需使用的对象当中。
DIP的英文解释大致为:
High-level modules shouldn’t depend on low-level modules. Both modules should depend on abstractions. In addition, abstractions shouldn’t depend on details. Details depend on abstractions.
解释过来就是,高层次的模块不应该依赖低层次的模块,不同的模块之间应该通过接口来互相访问,而并非直接访问到对方的具体实现。
清楚了这么多理论知识之后,接下来我们通过一些代码实战案例来进行更加深入的了解吧。
单一责任原则案例
我们来看这么一个类,简单的一个用户信息类中,包含了一个叫做home的字段,这个字段主要用于记录用户所居住的位置。
public class UserInfo { private String username; private short age; private short height; private String phone; private String home; }