看了《研磨设计模式》的工厂方法,其中涉及了这部分的内容,觉得很好,就将其摘抄下来,一方面和大家分享,另一方面做一个备份。
Ioc-Inversion of Control,控制反转
DI-Dependency Injection, 依赖注入
1、如何理解Ioc/DI
理清以下问题
(1)、参与者都有谁:一般有三方参与者,一个是某个对象;另一个是Ioc/DI容器;还有一个是某个对象的外部资源。
解释以下名词,某个对象:指的是任意的、普通的Java 对象。
Ioc/DI容器:指用来实现IoC/DI功能的一个框架程序。
某个对象的外部资源: 对象需要的,但是从外部获取的,都称为资源,如对象需要的文件资源等。
(2)、谁依赖谁:某个对象依赖于IoC/DI容器
(3)、为什么需要依赖:对象需要IoC/DI的容器来提供对象需要的外部资源。
(4)、谁注入谁:IoC/DI容器注入某个对象
(5)、到底注入什么:注入某个对象需要的外部资源
(6)、谁控制谁:IoC/DI容器控制对象
(7)、控制什么:主要是控制对象实例的创造
(8)、为何叫反转:常规情况下的应用程序,如果要在A中使用C,你会怎么做?一般是直接去创造C的对象,也就是说在A类中主动去获取所需要的外部资源C,这种情况叫正向。而反向的情况呢?就是A类不再主动去获取C,而是被动的等待,等待IoC/DI容器获取一个C的实例,然后反向地注入到A类中。
用图例示意以下,在没有IoC/DI的时候,常规A类使用C的示意图
当有了IoC/DI容器的时候,示意图变成了这样
(9)、依赖注入和控制反转是同一概念吗?
它们是对同一件事情的不同描述,只是它们描述的角度不同。
依赖注入:应用程序依赖容器创建并注入它所需要的外部资源。
控制反转:容器控制应用程序,由容器反向的向应用程序注入其所需要的外部资源。
2、工厂方法在某种角度上来说和IoC/DI的思想很相似
下面提供一个简单的例子程序:
/**
* A1 A2 C1 C2体现了IOC/DI 的思想,好好体会一下
*
*/
public abstract class A1 {
/**
* 工厂方法,创建C1,类似于从子类注入进来的途径
* @return C1的对象实例
*/
protected abstract C1 createC1();
public void t1(){
//这里需要使用C1类,可是不知道究竟是用哪一个,也就不主动去创建C1了,怎么办?
//反正会在子类里面实现,这样更省心,这里不用管怎么获取C1,直接使用就好了
createC1().tc();
}
}
public class A2 extends A1 {
protected C1 createC1() {
//真正的选择具体实现,并创建对象
return new C2();
}
}
public interface C1 {
public void tc();
}
public class C2 implements C1 {
public void tc() {
System.out.println("Test");
}
}
public class ClientTest {
public static void main(String[] args) {
A1 a1 = new A2();
a1.t1();
}
}