分层解耦(IOC-DI引入)

news2024/10/5 11:30:33

目录

一、为什么要解耦

二、示例分析

三、如何解除耦合?

四、控制反转和依赖注入-简述


一、为什么要解耦

  • 内聚:软件中各个功能模块内部的功能联系
  • 耦合:衡量软件中各个层/模块之间的依赖、关联的程度
  • 软件设计原则:高内聚低耦合。高内聚指的是模块内部的功能联系越紧密越好,比如在"员工管理"的service中,仅仅存放与员工相关的逻辑处理。低耦合指的是尽可能降低层与层之间或者模块与模块之间的依赖关联,最好能做到解除耦合

解除耦合之后,层与层之间就没有依赖了,即使service层的代码发生了变动,也不会影响controller层和dao层的代码,这样就增强了程序的灵活性和可扩展性

二、示例分析

在该程序中,conrtroller需要调用EmpService,直接new了一个EmpServiceA对象。

EmpServiceA是EmpService的实现。

如果我们要切换service实现,比如将EmpServiceA切换为EmpServiceB,如图:

此时controller层new的对象也需要改动,如图:

此时就发现,service的代码发生了变化,controller的代码也要跟着改动。即:controller层与service层之间的代码耦合了。

三、如何解除耦合?

要想解除耦合,controller层就不能直接new service层的实现类了,一旦new了service层的实现类,这两层之间就已经耦合起来了。

所以第一步,需要把new对象这一块的代码之间删掉,剩下部分如图:

如果现在直接运行controller中的方法就会报错,因为我们声明了empService变量,但是这个变量没有赋值,那么它的值就是null,在运行的时候就会报错:空指针异常。

第二步,提供一个容器,容器就是用来存东西的,在容器中,我们可以存储一些对象,假如我们现在想使用EmpserviceA这个实现类,我们只需要把这个类所创建出来的对象放在这个容器当中。如图:

接下来,controller程序在运行的时候,它需要依赖于EmpService,此时,我们可以到容器中去查找EmpService这个类型的对象,而A对象就是Empservie类型的,这时候,我们就可以从容器中找到这个对象,然后再将这个对象赋值给empService

接下来,程序运行的时候,empService就有值了,而这个对象就是从容器中拿到的。

这时候,如果我们要切换实现类,把实现类由EmpServiceA切换为EmpServiceB,这时我们可以基于EmpServiceB这个实现类创建对象放到容器当中,此时,controller在运行的时候,也需要一个EmpService类型的对象,而B对象就是这个类型,所以controller就通过容器拿到了B对象,再赋值给empService,然后就可以使用了。

此时我们发现,即使service层的实现类发生了变化,controller的代码也不需要改动,这样就完成了解耦。

四、控制反转和依赖注入-简述

要完成上述步骤,需要知道两个概念:控制反转和依赖注入。

  • 控制反转:Inversion Of Control,简称IOC。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。理解:原来在应用程序中,我们需要什么对象,都是直接new对象,而现在是将所有的对象都交给了容器来管理,这就是控制反转,反转之前是由应用程序自身来控制对象的创建,反转之后,是由容器来控制,这个容器称为IOC容器或者Spring容器。
  • 依赖注入:Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。比如controller程序在运行时,需要依赖empService这个资源,这时候可以让IOC容器来提供这个资源。该过程就称为依赖注入
  • Bean对象:IOC容器中创建、管理的对象,称之为bean。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1643689.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FilterListener详解

文章目录 MVC模式和三层架构MVC模式三层架构MVC和三层架构 JavaWeb的三大组件Filter概述快速入门过滤器API介绍过滤器开发步骤配置过滤器俩种方式修改idea的过滤器模板 使用细节生命周期拦截路径过滤器链 案例统一解决全站乱码问题登录权限校验验 ServletContextServletContext…

Java项目:基于SSM框架实现的高校专业信息管理系统设计与实现(ssm+B/S架构+源码+数据库+毕业论文+PPT+开题报告)

一、项目简介 本项目是一套基于SSM框架实现的高校专业信息管理系统 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观、操作简单、…

基于51单片机PWM控制直流电机—数码管显示

基于51单片机PWM控制直流电机 (仿真+程序+设计报告) 功能介绍 具体功能: 1.L298驱动直流电机; 2.数码管显示转动方向和PWM占空比(0-100%); 3.按键控制PWM占空比来加/…

Centos7网络处理name or service not known

1、编辑->虚拟网络编辑器 2、查看本机的ip 3、 /etc/sysconfig/network-scripts/ 查看文件夹下面的 ifcfg-eth33 后面的33可能不一样 vi /etc/resolv.conf 编辑文件添加以下DNS nameserver 114.114.114.114 4、设置本机的网络 5、ping www.baidu.com 先重启…

交叉导轨维护和保养的方法!

交叉导轨系统作为一种常见的机械传动装置,广泛应用于各种精密机械设备中。为了确保交叉导轨系统的正常运行和延长其使用寿命,定期维护和保养是至关重要的。 1、清洁:定期清理交叉导轨表面的灰尘、油污等杂质,保持其清洁。在清理过…

【C++】详解STL的容器之一:list

目录 简介 初识list 模型 list容器的优缺点 list的迭代器 常用接口介绍 获取迭代器 begin end empty size front back insert push_front pop_front push_back pop_back clear 源代码思路 节点设计 迭代器的设计 list的设计 begin() end() 空构造 ins…

公众号/小程序 开发模式切换

开发公众号/小程序 模式切换 https://ke.qq.com/course/6033257/14616022822424425#term_id106263577

QT5之lambda+内存回收机制

使用lambda需要 配置c11 所以在点.pro文件里面配置添加如下 CONFIG c11 使用到qDebug 打印包含头文件 #include<QDebug> lambda 表达式使用 代替槽如下 #include "mainwidget.h" #include<QPushButton> #include<QDebug> mainWidget::mainWid…

VGA接口驱动与图像显示动态移动(未完)

描述&#xff1a; 实现vga彩条显示&#xff0c;并以彩条为背景&#xff0c;显示一个200x200像素的白色方框&#xff08;可填充任意像素匹配的照片&#xff09;&#xff0c;可以实现如下移动规律&#xff1a; 水平方向和竖直方向的速度一样。当一个方向碰到边框的时候&#xff…

写爬虫代码抓取Asterank中小行星数据

2024年5月4日 问题来源 解决方案 回顾2023年7月14日自己写的爬虫代码 import requests import re import pandas as pd texts[] def getData(page):#每页评论的网址urlhttps://item.jd.com/51963318622.html#comment#添加headers&#xff0c;伪装成浏览器headers{User-Agent:…

Redis(基础指令和五大数据类型)

文章目录 1.基本介绍1.多种数据结构支持2.应用场景 2.Redis安装&#xff08;直接安装到云服务器&#xff09;1.安装gcc1.yum安装gcc2.查看gcc版本 2.将redis6.2.6上传到/opt目录下3.进入/opt目录下然后解压4.进入 redis-6.2.6目录5.编译并安装6.进入 /usr/local/bin 查看是否有…

udp/tcp回显网络编程

udp DatagramSocket 用于接收和发送udp数据报 构造方法&#xff1a; DatagramSocket():创建一个UDP数据报套接字的Socket&#xff0c;绑定到本地上 一个随机可用端口上&#xff0c;一般用于客户端DatagramSocket(int port):创建一个UDP数据报套接字的Socket&#xff0c;绑定到…

【Python项目】基于opencv的的【疲劳检测系统】

技术简介&#xff1a;使用Python技术、OpenCV图像处理库、MYSQL数据库等实现。 系统简介&#xff1a;用户可以通过登录系统平台实现实时的人脸照片的拍摄和上传&#xff0c;结合上传图像的内容进行后台的图像预处理和运算分析&#xff0c;用户可以通过照片分析界面查看到当前检…

Unity UGUI Image 点击事件忽略空白像素区域

我们会遇到图片不是方形的不规则图片。这个时候我们希望只有点击到图像内容本身才算点击&#xff0c;点击空白区域则不算点击。而UGUI对图片的处理是整个图片都会算作点击区域&#xff0c;这样不能满足于我们的使用需求了。 首先我们需要把图片本身的Read/Write 选项打开 然后…

深入了解 NumPy:深度学习中的数学运算利器

文章目录 1. 导入NumPy2. 创建NumPy数组3. 数组的算术运算4. N维数组4.1 创建和操作多维数组4.2 高维数组 5. NumPy的广播功能5.1 基本广播示例5.2 更复杂的广播示例 6. 访问数组元素6.1 基于索引的访问6.2 遍历数组6.3 基于条件的访问6.4 高级索引6.5 性能考虑 在深度学习和数…

「C++ STL篇 1-0」string类的使用

目录 〇、概念 一、string类的构造函数 二、赋值运算符重载 三、有关容量的操作 四、string对象的访问 五、遍历string对象的字符数组 六、string对象的修改 七、string对象的常用操作 八、字符串和数字间的转换 拓展】 练习】 源代码】 〇、概念 1. string类是什么&#xff1…

如何查看Windows 10故障日志和错误日志?这里提供详细步骤

序言 当你的计算机崩溃时,会生成一个崩溃日志,可以帮助你分析崩溃的原因。但是,你知道如何查看Windows 10崩溃日志和错误日志吗?如果你不知道,别担心。这篇文章将向你展示如何使用两种方法查看Windows10崩溃日志。 使用事件查看器查看Windows 10故障日志 要查看Windows…

【Java】基本程序设计结构(一)

前言&#xff1a;现在&#xff0c;假定已经成功安装了JDK&#xff0c;并且能够运行上篇示例程序。本篇将开始介绍Java程序中的基本设计结构&#xff0c;其中包括&#xff1a;一个简单的Java应用&#xff0c;注释&#xff0c;数据类型&#xff0c;变量与常量&#xff0c;运算符&…

对于子数组问题的动态规划

前言 先讲讲我对于这个问题的理解吧 当谈到解决子数组问题时&#xff0c;动态规划(DP)是一个强大的工具&#xff0c;它在处理各种算法挑战时发挥着重要作用。动态规划是一种思想&#xff0c;它通过将问题分解成更小的子问题并以一种递归的方式解决它们&#xff0c;然后利用这些…

Linux(openEuler、CentOS8)基于chrony企业内网NTP服务器搭建实验

一、知识点 chrony 是由 守护进程 chronyd 以及 命令行工具 chronyc 组成的 chronyd 在后台静默运行并通过 123 端口与时间服务器定时同步时间&#xff0c;默认的配置文件是 /etc/chrony.conf chronyc 通过 323 端口与 chronyd 交互&#xff0c;可监控 chronyd 的性能并在运…