0

Spring IOC 为什么能降低耦合 - 说故事的五公子

 1 year ago
source link: https://www.cnblogs.com/wugongzi/p/16413624.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

有同学在学习 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 就是利用工厂模式+反射实现自动生产对象,管理对象生命周期的功能。降低了代码的耦合

总结

  • 依赖注入的意思是你需要的东西不是由你创建的,而是第三方,或者说容器提供给你的。这样的设计符合正交性,即所谓的松耦合。
  • 依赖注入是调用者仅通过声明某个组件就可以获得组件的控制权,而对该组件的依赖关系管理、查找、加载由外部完成。
  • 依赖注入就是你不用关心对象的生命周期,什么时候被创建,什么时候销毁,只需直接使用即可,对象的生命周期由提供依赖注入的框架来管理。

__EOF__


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK