分层解耦
问题引出
之前在处理请求与响应时,我们接收客户端的请求,调用数据库或者接口获取到需要的数据时,逻辑处理返回给客户端。我们都知道Java是面向对象编程,但是我们的代码都写在一个类中,没有遵守面向对象七大原则中的单一职责原则,分工不明确,非常不利于后期的修改维护与拓展。举个例子,我们需要对不同用户在性别这个属性的值上显示男女或男士女士,但是我们现在修改的话,会有很多重复的代码不能复用导致产生很多冗余的代码。所以我们需要把代码按照一定的逻辑进行分层。
分层思路
根据代码的分工划分,我们把代码分成三类
- Controller(控制层):负责接收前端传回的数据,对请求进行处理,通过调用Service层的方法获取到数据后响应给前端。
- Service(业务逻辑层):负责处理具体的业务逻辑,调用Dao层对应的方法获取需要的数据,供控制层去调用获取。
- Dao(数据访问层&持久层):负责数据访问操作(增删改查),是直接与数据库交互的一层,供业务逻辑层调用。
分层结构
分层后的优缺点对比,可以看出分层可以让我们的项目逻辑更加清晰,效率也得到提高。
高内聚低耦合
高内聚:
内聚指的是模块内部各元素之间的紧密程度。高内聚意味着模块内部各个元素(如函数、变量等)之间的关联度高,共同完成一个明确且单一的功能。高内聚的模块具有以下优点:
- 功能明确:模块的功能单一且明确,易于理解和维护。
- 减少错误:模块内部元素之间的关联紧密,减少了错误传播的可能性。
- 可重用性:高内聚的模块更容易被其他项目或模块重用。
低耦合:
耦合是指模块之间依赖关系的强弱。低耦合意味着模块之间的依赖关系较少,每个模块可以相对独立地工作。低耦合的模块具有以下优点:
- 独立性:模块之间的独立性较高,一个模块的变化不会对其他模块产生太大影响。
- 易于测试:低耦合的模块更易于进行单元测试和集成测试。
- 可扩展性:当需要添加新功能或修改现有功能时,低耦合的设计使得这些变更更加容易实施。
虽然我们对代码进行了分层,解决了内聚问题,但是还存在者耦合的问题。还是从我们最先开始的问题出发,我们需要对不同用户在性别这个属性的值上显示男女或男士女士,那么我们需要在Service层写两个类,一个显示男,一个显示男士。但是对于Controller层来说每一次调用就需要修改该接口类的引用对象,如果需要修改接口实现类的类名时,Controll层就会报错。所以不同类之间耦合度太高了。
IOC和DI
IOC(控制反转):对象创建权交由程序自身转移到外部容器(springboot容器),这种思想称控制反转。
DI(依赖注入):容器为应用程序运行时,提供所需的依赖资源,称为依赖注入。
Bean对象:在IOC容器中创建和管理的对象,称之为bean,通常他们的命名为类名首字母小写,当然也可以自定义,这就需要通过给注解传递值去修改(如图@注解名(“自定义名称”))。
同样对于类对象的控制反转,也就放到容器中我们是用注解的形式,为了规范规定了,不同层之间用不同的注解方式。
依赖注入也是用注解的方式在需要注入的语句上方添加即可。
这种依赖注入是根据类名寻找容器中对应的对象的,但是如果某个接口类有多个实现类时呢,我们直接依赖注入会发生什么呢?
很明显会报错,因为两个类编译器也不知道选择哪个,这个时候我们有如下方法
第一个是在控制反转时,告诉容器哪个优先级最高则调用哪个。
第二和第三个都是给应用程序提供需要注入的bean对象的名称,但是这两个有不同的地方。
Bean组件扫描
注解之所以能够起作用,其底层是依赖于bean组件对包进行扫描。
如果想要组件对指定的包进行扫描则需要给注解传递一个数组,也就是传递需要的扫描的包名,如果手动配置扫描,就会覆盖原先默认的路径,所以需要再加入默认的包。