Spring IOC 为什么能降低耦合
有同学在学习 Spring 框架中可能会问这样的问题,为什么通过依赖注入就可以降低代码间的耦合呢?我通过 new 生产对象不也可以吗,不就是一行代码的不同,一个是 @Resource 注入,一个是 new 创建,怎么就降低耦合了?
今天博主就带大家来一步步剖析这个问题
一、传统方式创建对象
通常我们是这样创建对象的
WuliCar wuli = new WuliCar();
wuli.run();
第一天:二明想用一辆车,然后通过 new 搞了一辆五菱荣光,调用 run 方法开始使用,车子跑起来了,很高兴。
一个月后:二明公司赚钱了,不想开五菱了,想换辆宝马,接下来二明一顿操作:
BaomaCar baoma = new BaomaCar();
baoma.run();
很好,车子从五菱换成了宝马,跑起来了,很高兴。
半年后:二明公司赚大钱了,二明想搞辆直升机,接下来又一顿操作
ZhiShenJi zhi = new ZhiShenJi();
zhi.fly();
这次改动比较大,宝马换成直升机,run 换成了 fly。
看到这里先思考一下,不想往下看,这样做有什么问题吗?
思考时间到,我们接着往下看。
从代码看好像没多大问题,不就改了两行代码嘛,这有啥。你想想,如果你的代码中有 1000 个地方都是这么写的,你想把宝马换成直升机岂不是要改 1000 次,run 改成 fly 又要改 1000 次,晚上别想下班了。
二、接口编程
经过上次一顿操作,二明加了好几天班才弄完,二明想想每天这么搞不得累死,不行,得想想办法。于是二明脑子一转了,一想就想到了。我定义好一些方法,大家都按照这个规则来,不就好了。
public interface vehicle {
// 定义一个交通工具接口,有一个 work 方法
void work();
}
宝马实现这个接口:
public class Baoma implements vehicle {
@Override
public void work() {
System.out.println("宝马跑起来");
}
}
飞机实现这个接口:
public class ZhiShenJi implements vehicle {
@Override
public void work() {
System.out.println("直升机飞起来");
}
}
经过上面改造后,后面二明想把宝马换成直升机的时候只需要修改 new 那块就可以了,省了很多时间
三、工厂方法
利用接口确实好一些了,但是问题还是没有解决。为了提高内聚性,专职类负责特定的事情,所以我们使用一个类作为工厂类,既能生产 Car 又能生产 ZhiShenJi
class VehicleFactory{
VehicleFactory(){}
public static Vehicle getInstance(String type){
Animal result = null;
if("car".equals(type)){
result = new Car();
}
if("zhishenji".equals(type)){
result = new ZhiShenJi();
}
return result;
}
}
如果有一次我想锻炼身体,想骑自行车了,那么很简单
class VehicleFactory{
VehicleFactory(){}
public static Vehicle getInstance(String type){
Animal result = null;
if("car".equals(type)){
result = new Car();
}
if("zhishenji".equals(type)){
result = new ZhiShenJi();
}
if("zixingche".equals(type)){
result = new ZiXingChe();
}
return result;
}
}
Vehicle vehicle = VehicleFactory.getInstance("zixingche");
vehicle.work();
这种方法把创建对象的过程交给了一个专业的类(Factory),我只需要告诉他我需要什么(参数),他就会返回给我正确的对象,只是解决了内聚性的问题,但是他并没有解决我的声明语句七零八落的散落在程序中,我还是需要去将参数从car
替换为zixingche
四、反射
后来二明想到一个更绝妙的主意.我在写程序的时候不告诉工厂我需要什么,等到运行的时候我再告诉工厂我需要什么,再利用反射技术给我生产出来不就可以了吗?二明说干就干
Vehicle vehicle = VehicleFactory.getInstance(读取配置文件);
vehicle.work();
我想要的:zixingche
zixingche.work();
大功告成,这样我要什么,都写在一个配置文件中,利用反射技术就可以创建好,这样我就不用在生产了,下次换车的时候直接去配置文件中修改就好了,代码中不用修改。
对于生产对象这件和业务没有直接关系的事情,我们已经提取给了专业的工厂,专业的工厂还是根据配置文件进行的生产,想生产什么我只需要改一处即可,这就是降低了耦合性(生产对象和业务之间的耦合,让生产对象对业务的影响降到了最低)。
五、Spring IOC
上面第四点说的那些功能,Spring IOC 已经帮助我们实现了,Spring IOC 就是利用工厂模式+反射实现自动生产对象,管理对象生命周期的功能。降低了代码的耦合
总结
- 依赖注入的意思是你需要的东西不是由你创建的,而是第三方,或者说容器提供给你的。这样的设计符合正交性,即所谓的松耦合。
- 依赖注入是调用者仅通过声明某个组件就可以获得组件的控制权,而对该组件的依赖关系管理、查找、加载由外部完成。
- 依赖注入就是你不用关心对象的生命周期,什么时候被创建,什么时候销毁,只需直接使用即可,对象的生命周期由提供依赖注入的框架来管理。
Spring IOC 为什么能降低耦合的更多相关文章
- spring的作用是减低耦合,从编译器降低,例如不直接通过new方式 而是通过工厂方式获取对象
spring的作用是减低耦合,从编译器降低,例如不直接通过new方式 而是通过工厂方式获取对象
- [Spring框架]Spring IOC的原理及详解。
这里感谢 CSDN 的原博客:http://blog.csdn.net/m13666368773/article/details/7802126 看后 受益匪浅,这里再重温一遍Spring IOC ...
- Spring+IOC(DI)+AOP概念及优缺点
Spring pring是一个轻量级的DI和AOP容器框架. 说它轻量级有一大部分原因是相对与EJB的(虽然本人从没有接触过EJB的应用),重要的是,Spring是非侵入式的,基于spring开发的应 ...
- Spring ioc与aop的理解
一 spring的特点 1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很容易 ...
- Spring(2)——Spring IoC 详解
Spring IoC 概述 IoC:Inverse of Control(控制反转) 读作"反转控制",更好理解,不是什么技术,而是一种设计思想,就是将原本在程序中手动创建对象的控 ...
- 案例学编程系列:案例认识 Spring IOC
本文spring libs 地址:https://github.com/yizhiamumu/springlibs Spring 能帮我们做什么 ①.Spring 能帮我们根据配置文件创建及组装对象之 ...
- Spring IOC容器的实现原理
1 概述 1.1 依赖反转模式 在Java中,一个复杂的功能一般都需要由两个或者两个以上的类通过彼此合作来实现业务逻辑的,这使得每个对象都需要与其合作的对象的引用.如果这个获取依赖对象的过程需要自己去 ...
- spring IOC理解
用spring做了几个项目后发现,对spring的IOC理解还是不够清晰,今天就来总结下自己的理解(个人的一些见解) 以前用jsp+servlet做网站时,只是分了显示层(jsp),控制层(servl ...
- 关于Spring IOC (DI-依赖注入)需要知道的一切
关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 <Spring入门经典>这本书无论对于初学者或者有 ...
随机推荐
- 如丝般顺滑:DDD再实践之类目树管理
在上次反思DDD实践之后,在类目树管理项目中再次实践DDD.从需求分析到建模和具体的落地,结合个人体会,都是干货.
- Java学习day8
今天学习了package,import,final,static和多态 package可以理解为文件夹,因为有些类可能重名,如果在同一个目录下就无法正常实现,所有需要有不同的包来装对应的类 Java出 ...
- 安卓记账本开发学习day5之版本兼容问题
安卓5.0以上版本想要隐藏DatePicker头布局的写法比较复杂,需要一层一层隐藏 int headerId = getContext().getResources().getIdentifier( ...
- JavaWeb学习day3-Maven&安装
1.官网下载:https://maven.apache.org/ 2.解压下载好的压缩包 3.配置环境变量 添加如下图变量 在path变量下添加下图 4.安装完成检测 cmd输入:mvn -versi ...
- OpenHarmony 3.1 Release版本发布
OpenHarmony 3.1 Release 版本概述 当前版本在OpenHarmony 3.1 Beta的基础上,更新支持以下能力: 标准系统基础能力增强 本地基础音视频播放能力.视频硬编解码.相 ...
- java高级用法之:在JNA中使用类型映射
目录 简介 类型映射的本质 TypeMapper NativeMapped 总结 简介 JNA中有很多种映射,library的映射,函数的映射还有函数参数和返回值的映射,libary和函数的映射比较简 ...
- Java并发编程之Lock(同步锁、死锁)
这篇文章是接着我上一篇文章来的. 上一篇文章 同步锁 为什么需要同步锁? 首先,我们来看看这张图. 这是一个程序,多个对象进行抢票. package MovieDemo; public class T ...
- 领域驱动模型DDD(三)——使用Saga管理事务
前言 虽然一直说想写一篇关于Saga模式,在多次尝试后不得不承认这玩意儿的仿制代码真不是我一个菜鸟就能完成的,所以还是妥协般地引用现成的Eventuate Tram Saga框架(虽然我对它一直很反感 ...
- python基础-基本数据类型(一)
一.什么是数据类型 编程语言通过计算机的一些物理底层机制创造出不同类型的数据,用来表示现实世界中的不同信息,以便于计算机更好的存储和计算. python中常见的数据类型有: 1.数值类型 名称 描述 ...
- .NET桌面程序应用WebView2组件集成网页开发4 WebView2的线程模型
系列目录 [已更新最新开发文章,点击查看详细] WebView2控件基于组件对象模型(COM),必须在单线程单元(STA)线程上运行. 线程安全 WebView2必须在使用消息泵的UI线程上创 ...