首先上一段传统的编程代码:
//定义一个ReportGenerator接口,规范了一个generate方法
public interface ReportGenerator {
public void generate(String tableName);
}
//定义了一个ExcelGenerator类,实现了ReportGenerator接口
public class ExcelGenerator implements ReportGenerator {
//根据tableName生成一个Excel报表
@Override
public void generate(String tableName) {
System.out.println("生成"+tableName+"的excel报表");
}
}
//定义了一个PDFGenerator类,实现了ReportGenerator接口
public class PDFGenerator implements ReportGenerator {
//根据tableName生成一个PDF报表
@Override
public void generate(String tableName) {
System.out.println("生成"+tableName+"的PDF报表");
}
}
//定义一个报表生成器ReportService,专用于生成报表
public class ReportService {
private ReportGenerator generator1 = new PDFGenerator();//创建pdf类的实例,用于生成PDF报表
private ReportGenerator generator2 = new ExcelGenerator();//创建pdf类的实例,用于生成Excel报表
//日粒度,生成PDF版的报表
public void getDailyReport(String tableName){
String table = "Date"+tableName;
generator1.generate(table);
}
//月粒度,生成Excel版的报表
public void getMonthlyReport(String tableName){
String table="Month"+tableName;
generator2.generate(table);
}
}
public class Client {
public static void main(String[] args) {
ReportService reportService = new ReportService();
reportService.getDailyReport("123");//生成日粒度报表
reportService.getMonthlyReport("456");//生成月粒度报表
}
}
每个类的注释写的很详细,就不再说一遍了。从这个代码里,我们发现:
报表生成器由 ReportService 类是通过实例化PDF和Excel两个类,然后调用两个类的方法来实现的,这里面就产生了一个问题,ReportService 类依赖了PDF和Excel两个类(换句话说就是,ReportService 类和PDF和Excel两个类紧耦合了,以后如果要修改PDF和Excel类,都要修改ReportService类。不利于大系统的升级修改,显然这不是我们想要的。)。
有什么解决办法吗?用控制反转思想解决问题。即:
引入一个中间管理者,也就是容器(Container),由其统一管理PDF和Excel的对象。(Spring中称为是组件,或者称为 Bean)。当我们的ReportService 类想要调用PDF和Excel的对象时,通过请求Container,然后Container把相应的对象给ReportService 类。而不用ReportService 类自己去通过硬编码方式去new一个对象,然后再使用。通过Container,将ReportService 类和PDF和Excel类解耦了,以后要修改PDF和Excel类,可以不用动ReportService 类了。说的轻松,那如何实现这个中间管理者呢(Container)?
我们不用管如何实现,只要按照Spring的配置规则走就行了,可以把Spring框架理解为就是这样一个中间管理者,帮助我们管理程序中诸多的java类(又称为bean)。