初识IoC

Spring的两大核心概念一个是Inversion of Control,一个是Dependency Injection。我们先来梳理一下什么是IoC?IoC的抽象概念是“依赖关系的转移”。例如程序中有两个类A和B。A类中要使用B类中定义的方法,我们通常的做法是在A类中实例化B类一个对象,从而达成调用B类方法的目的。这样做会产生什么问题呢?这样的设计方式,会让A类依赖于B类,也就是说高层模块不应该依赖于低层模块,而模块都必须依赖于抽象,也就是说应该依赖于接口。看一下如下代码:

package ray.spring;

public class Business {

	private IDeviceWriter writer;

	public IDeviceWriter getWriter() {
		return writer;
	}

	public void setWriter(IDeviceWriter writer) {
		this.writer = writer;
	}
	
	public void save() {
		if (writer == null) {
			throw new RuntimeException("Device Writer needed...");
		}
		writer.saveToDevice();
	}
}

通过接口声明,可以达到重复使用Business类的目的。在遇到存档需求时,可以设计为依赖于IDeviceWriter接口,而不是依赖于实际的FloppyWriter。例如:

package ray.spring;

public interface IDeviceWriter {

	void saveToDevice();

}

在这样的设计下,Business类就是可以重用的。如果今天有储存至Floppy或USB磁盘的需求,只要针对这两种存储需求分别实现IDeviceWriter接口即可。例如:

package ray.spring;

public class FloppyWriter implements IDeviceWriter {

	@Override
	public void saveToDevice() {
		System.out.println("数据存储在软盘上");
	}

}

package ray.spring;

public class UsbDiskWriter implements IDeviceWriter {

	@Override
	public void saveToDevice() {
		System.out.println("数据存储在U盘上");
	}

}

编写一个配置管理程序,通过一个简单的XML或是.properties文件来更改配置,就可以简单地更换Business类所依赖的IDeviceWriter实现。例如:

package ray.spring;

import java.io.FileInputStream;
import java.util.Properties;

public class BusinessFactory {

	private IDeviceWriter writer;
	private Business business;
	private Properties properties;
	private static BusinessFactory factory;
	
	public BusinessFactory() throws Exception {
		properties = new Properties();
		properties.load(new FileInputStream("config.properties"));
		String businessClass = properties.getProperty("business.class");
		String writerClass = properties.getProperty("writer.class");
		business = (Business) Class.forName(businessClass).newInstance();
		writer = (IDeviceWriter) Class.forName(writerClass).newInstance();
		business.setWriter(writer);
	}

	public IDeviceWriter getWriter() {
		return writer;
	}

	public Business getBusiness() {
		return business;
	}

	public static BusinessFactory getInstance() throws Exception {
		if (factory == null) {
			return new BusinessFactory();
		}
		return factory;
	}
	
}

package ray.spring;

public class Main {

	public static void main(String[] args) {
		try {
			Business business = BusinessFactory.getInstance().getBusiness();
			business.save();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

IoC的Control是控制的意思,其实背后的意义也是一种依赖关系的转移。如果A依赖B,其意义即B拥有控制权。如果转移这种关系(依赖关系的反转即控制关系的反转),将控制权由实现的一方转移至抽象的一方,让抽象方拥有控制权,可以获得组件的可重用性。在上面的Business程序中,整个控制权从实际的FloppyWriter转移至抽象的IDeviceWriter接口上,让Business依赖于IDeviceWriter接口,且FloppyWriter、UsbDiskWriter也依赖于IDeviceWriter。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值