Ioc&DI和Sping框架简介

我们将根据一个例子来逐步了解 例子的详细内容:例子
例子的功能:
在这里插入图片描述
实现一:以面向对象的方式实现Demo
html报表

public class HtmlReportGenerator {
	public void generate(){
		System.out.println("生成Html格式的报表!");
	}
}

pdf报表

public class PdfReportGenerator {
	public void generate(){
		System.out.println("生成Pdf格式的报表!");
	}
}

报表服务类

public class ReportService {
	
	PdfReportGenerator pdfGenerator=new PdfReportGenerator();
//	HtmlReportGenerator htmlGenerator = new HtmlReportGenerator();
	
	public void generateReport(){
		System.out.println("收集、汇总数据!");
		System.out.println("生成柱状图等图标!");
		pdfGenerator.generate();
//		htmlGenerator.generate();
	}

}

在报表服务类中我们需要哪一种报表就实例化哪种报表

实现二:分离接口和实现

  • 优化目标:消除ReportService到ReportGenerator实现类之间的依赖关系
    在这里插入图片描述
    实现一个报表接口类ReportGenerator
public interface ReportGenerator {
	public void generate();
}

其他的报表类需要实现ReportGenerator接口并实现generate方法,这里省略其他

public class PdfReportGenerator implements ReportGenerator {

	@Override
	public void generate() {
		// TODO Auto-generated method stub
		System.out.println("生成Pdf格式的报表!");
	}
}

报表服务类

public class ReportService {
	
	ReportGenerator generator;
	
	public void setGenerator(ReportGenerator generator) {
		this.generator = generator;
	}

	public void generateReport(){
		System.out.println("收集、汇总数据!");
		System.out.println("生成柱状图等图标!");
		generator.generate();
	}
	
	public static void main(String[] args) {
		PdfReportGenerator pdf = new PdfReportGenerator();
		HtmlReportGenerator html = new HtmlReportGenerator();
		ReportService service = new ReportService();
		service.setGenerator(html);
		service.generateReport();
	}

}

由于抽象了一个报表接口,需要哪种报表,在报表服务端指定报表接口

实现三:采用容器

  • 增加容器类:Container类
  • 所有组件由Container类管理
    在这里插入图片描述
    容器类
public class Container {

	private static Container instance;
	private Map<String, Object> components;

	private Container() {
		components = new HashMap<String, Object>();
		instance = this;
		
		ReportGenerator reportGenerator = new PdfReportGenerator();
		components.put("reportGenerator", reportGenerator);

		ReportService reportService = new ReportService();
		components.put("reportService", reportService);

	}
	
	public static Container getInstance(){
		if(instance == null)
			instance = new Container();
		return instance;
	}

	public Object getComponent(String key) {
		return components.get(key);
	}
}

测试类

public class Run {
	public static void main(String[] args) {
		
		ReportService reportService = (ReportService) Container.getInstance().getComponent("reportService");
		reportService.generateReport();
	}
}

容器来帮我们new报表类
我们只需要传入所需要的报表类型,容器返回我们那个报表对象

分析:

  • ReportService与ReportGenerator的具体实现解耦了
    • 选择不同的Generator不需要修改Service
  • 缺点
    • Container对所管理的所有组件产生了依赖
    • ReportService对Container依赖,因为其封装有查找逻辑,所以在重用之前还要修改
  • 目标
    • 去掉ReportService对Container依赖

实现四:使用服务定位器

  • 服务定位器:ServiceLocator类

    • 封装查找逻辑
    • 对外公开查找组件(Generator)的方法、

在这里插入图片描述
服务定位器,将查找报表的那个方法分离出来

public class ServiceLocator {

	private static Container container = Container.getInstance();
	
	public static ReportGenerator getReportGenerator(){
		return (ReportGenerator) container.getComponent("reportGenerator");
		
	}
}

  • 优点:
    • 应用服务定位器将查找逻辑从组件里分离出来
    • 降低组件在查找方面的复杂性
    • 增加组件的重用性
  • 这是用于查找资源的通用设计模式,并不局限于查找组件
    • JavaEE中的应用,如:JNDI(Java命名和目录接口)
  • 局限
    • 组件需要知道如何查找资源

概念

  • Ioc(Inversion of Control,控制反转):
    • 设计原则,解耦组件之间的依赖关系
  • DI(DI(Dependency Injection ,依赖注入):
    • 具体的设计模式,体现了IoC的设计原则
    • 因为DI是IoC最典型的实现,所以术语IoC与DI经常被混用

实现五
在这里插入图片描述

  • 不需要服务定位器
    • 组件(ReportService)增加接受资源的方法(setter)
    • 由容器将组件(ReportGenerator)注入到另一个组件(ReportService)
  • 优点
    -完全面向接口

不同类型的依赖注入

  • 主要有三种类型的DI
    • 接口注入
    • setter注入
    • 构造器注入

在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值