参考轻松理解 Java开发中的依赖注入(DI)和控制反转(IOC)、Java:控制反转(IoC)与依赖注入(DI)、依赖注入Dependency Injection-依赖注入详解
一、依赖注入
依赖注入是一个常见的专业名词,但是较难理解。我觉得这个是因为依赖注入这个思想,其实就藏在面对对象的编程中。
就好像每个人都会吃饭,但有一天突然要你科学解释,什么叫做咀嚼,你肯定也会不知所措。
所以个人感觉可以解释为:注入依赖对象。
1、什么叫注入
有些人对于注入不太理解。用一个简单的例子来解释一下
我们有个Task类
public class Task {
private String taskName;
public Task(String taskName) {
this.taskName = taskName;
}
}
此时我们main函数的代码如下所示:
public static void main(String[] args) {
Task task = new Task("Task #1");
}
Task的name,从main函数输入,这种行为就叫做注入。
2、什么是依赖
我们先建立一个Java程序员类
public class Javaer {
private String name = "张三";
public void writeCode() {
System.out.println(this.name + " is writing java code");
}
}
我们修改Task代码如下
public class Task {
private String taskName;
private Javaer javaer;
public Task(String taskName) {
this.taskName = taskName;
this.javaer = new Javaer("张三");
}
public void start() {
System.out.println("Task " + this.taskName + " started");
javaer.writeCode();
}
}
Task有了Javaer属性,Javaer就叫做Task的依赖。
进一步解释就是:任务需要依赖程序员完成,现在Task,有了Javaer类这个属性,需要Javaer类的帮助,才能完成自己的start()功能。
Task里面this.javaer = new Javaer("张三");,这以后我们想要李四来完成任务的时候,我们应该怎么办,如果是面向过程的变成思想,最终会变成以下代码
public class Task {
private String taskName;
private Javaer javaer;
public Task(String taskName) {
this.taskName = taskName;
}
public void zhangSanStart() {
this.javaer = new Javaer("张三");
System.out.println("Task " + this.taskName + " started");
javaer.writeCode();
}
public void liSiStart() {
this.javaer = new Javaer("李四");
System.out.println("Task " + this.taskName + " started");
javaer.writeCode();
}
}
main调用如下
public static void main(String[] args) {
Task task = new Task("任务名1");
task.zhangSanStart();
Task task2 = new Task("任务名2");
task2.liSiStart();
}
结果如下
Task 任务名1 started
张三 is writing java code
Task 任务名2 started
李四 is writing java code
一切看似正常运行,但以后要王五,赵六来完成任务的时候,岂不是需要一直修改Task代码?
这时候就需要依赖注入。
3、依赖注入介绍
有些人可能明白了,依赖注入就是同时拥有依赖、注入。
现在我们再次对Task进行修改
public class Task {
private String taskName;
private Javaer javaer;
public Task(String taskName, Javaer javaer) {
this.taskName = taskName;
this.javaer = javaer;
}
public void start() {
System.out.println("Task " + this.taskName + " started");
this.javaer.writeCode();
}
}
main如下所示
public static void main(String[] args) {
Javaer javaer = new Javaer("张三");
Task task = new Task("任务一", javaer);
task.start();
}
结合我们之前的所说,注入是其它函数的输入,若注入的是依赖呢?
就叫做依赖注入。
二、控制反转
反转的意思比较好理解,就是从主动,变为被动。
现在我们的Task,只能由Java程序员完成,我们若要让Php程序员完成要怎么做呢?
方案一(不好的方案)
新建一个Phper类
public class Phper {
private String name;
public Phper(String name) {
this.name = name;
}
public void writeCode() {
System.out.println(this.name + " is writing php code");
}
}
修改我们的Task类
public class Task {
private String taskName;
private Javaer javaer;
private Phper phper;
public Task(String taskName) {
this.taskName = taskName;
}
public void javaerStart() {
System.out.println("javaer start work");
this.javaer.writeCode();
}
public void phperStart() {
System.out.println("phper start work");
this.phper.writeCode();
}
public void setJavaer(Javaer javaer) {
this.javaer = javaer;
}
public void setPhper(Phper phper) {
this.phper = phper;
}
}
我们的main函数
public static void main(String[] args) {
Javaer javaer = new Javaer("java程序员");
Phper phper = new Phper("php程序员");
Task task = new Task("新任务");
task.setJavaer(javaer);
task.javaerStart();
Task task2 = new Task("新任务2");
task2.setPhper(phper);
task2.phperStart();
}
运行结果
javaer start work
java程序员 is writing java code
phper start work
php程序员 is writing php code
可以看见,程序正确运行,但如果要添加C程序员的时候,我们就除了添加C程序员的类以外,还需要修改Task,这并不是我们希望的。
方案2(好方案,控制反转)
涉及接口和多态,不太熟悉的朋友建议参考这篇文章Java接口 | 菜鸟教程
由于Javaer和Phper等等,都是程序员,我们新建一个接口Coder。
public interface Coder {
public void writeCode();
}
修改javaer和phper,让其都实现coder接口(关于继承不懂的可以看这篇文章)
public class Javaer implements Coder {
private String name;
public Javaer(String name) {
this.name = name;
}
@Override
public void writeCode() {
System.out.println(this.name + " is writing java code");
}
}
public class Phper implements Coder {
private String name;
public Phper(String name) {
this.name = name;
}
@Override
public void writeCode() {
System.out.println(this.name + " is writing php code");
}
}
Task如下所示
public class Task {
private String taskName;
private Coder coder;
public Task(String taskName) {
this.taskName = taskName;
}
public void setCoder(Coder coder) {
this.coder = coder;
}
public void start() {
System.out.println("Task " + this.taskName + " start");
this.coder.writeCode();
}
}
主函数如下所示
public static void main(String[] args) {
Javaer javaer = new Javaer("java程序员");
Phper phper = new Phper("php程序员");
Task task = new Task("新任务");
task.setCoder(javaer);
task.start();
Task task2 = new Task("新任务2");
task2.setCoder(phper);
task2.start();
}
Task 新任务 start
java程序员 is writing java code
Task 新任务2 start
php程序员 is writing php code
我们可以发现,原本是Task类,指定执行者,现在Task类的执行者是被其他代码指定,Task交出赋值权, 从主动赋值到被动赋值, 这就是控制反转。
本文深入解析Java开发中的依赖注入(DI)和控制反转(IOC)概念,通过实例讲解了依赖注入的基本原理,以及控制反转如何改变对象之间的依赖关系,使代码更灵活、易于维护。
胎教级别的依赖注入DI和控制反转IOC思想讲解&spm=1001.2101.3001.5002&articleId=107555593&d=1&t=3&u=b7ceb36cc319428d9af575f629b422f3)
3068

被折叠的 条评论
为什么被折叠?



