当前位置:网站首页>"Inversion of Control" and "Dependency Inversion", can't you tell the difference?
"Inversion of Control" and "Dependency Inversion", can't you tell the difference?
2022-08-08 09:29:00 【InfoQ】
- 控制反转(IoC)是什么?「反转」到底反转了什么?
- Spring和IOC之间是什么关系?
- 依赖注入(DI)和依赖倒置原则(DIP)又是什么?
- IOC、DI和DIP有什么关系?
1. 控制反转(IoC)
1.1 一个典型案例
public class UserServiceTest {
public static boolean doTest() {
//此处编写自己的判断逻辑
return false;
}
public static void main(String[] args) {
if (doTest()) {
System.out.println("Test succeed.");
} else {
System.out.println("Test failed.");
}
}
}
main
public abstract class TestCase {
public void run() {
if (doTest()) {
System.out.println("Test succeed.");
} else {
System.out.println("Test failed.");
}
}
public abstract boolean doTest();
}
public class JunitApplication {
private static final List<TestCase> cases = new ArrayList();
public static void register(TestCase testCase){
cases.add(testCase);
}
public static void main(String[] args) {
for(TestCase testCase : cases){
testCase.run();
}
}
}
UserServiceTest
TestCase
doTest
public class UserServiceTestCase extends TestCase{
@Override
public boolean doTest() {
//此处编写自己的判断逻辑
return false;
}
}
//注册测试用例
JunitApplication.register();
main
1.2 IoC概念的提出
inversion of control

1.3 为什么提出IoC

class A{
Object b = new B();
...
}
class B{
Object c = new C();
Object d = new D();
...
}
class C{
Object d = new D();
}
A
B



Servlet
Servlet
// 方式1
private MySQLDao dao = new MySQLDaoImpl();
// 方式2
private MySQLDao dao = (MySQLDao) BeanFactory.getBean("mySQLDao");
dao
dao
MySQLDaoImpl
mySQLDao
1.4 Spring和IoC的关系
1.5 面试中被问到IoC怎么回答
2. 依赖注入(DI)
2.1 定义
new()
Controller
Service
@Api(tags = {"报警联系人接口"})
@RestController
@RequestMapping("/iot/contact")
public class AlarmContactController extends BaseController {
// 这就是大名鼎鼎的DI啊,是不是非常简单!
@Autowired
private IAlarmContactService alarmContactService;
...
}
2.2 面试中被问到「依赖注入」怎么回答
3. 依赖倒置原则(DIP)
3.1 定义
- 高层模块(high-level modules)不要直接依赖低层模块(low-level);
- 高层模块和低层模块应该通过抽象(abstractions)来互相依赖;
- 抽象(abstractions)不要依赖具体实现细节(details),具体实现细节(details)依赖抽象(abstractions).
3.2 代码示例
/**
* @author 蝉沐风
* @desc 福特汽车厂商提供的接口
*/
public class FordCar{
public void run(){
System.out.println("福特开始启动了");
}
public void turn(){
System.out.println("福特开始转弯了");
}
public void stop(){
System.out.println("福特开始停车了");
}
}
/**
* @author【蝉沐风】
* @desc 本田汽车厂商提供的接口
*/
public class HondaCar {
public void run() {
System.out.println("本田开始启动了");
}
public void turn() {
System.out.println("本田开始转弯了");
}
public void stop() {
System.out.println("本田开始停车了");
}
}
/**
* @author【蝉沐风】
* @desc 自动驾驶系统
*/
public class AutoDriver {
public enum CarType {
Ford, Honda
}
private CarType type;
private HondaCar hcar = new HondaCar();
private FordCar fcar = new FordCar();
public AutoDriver(CarType type) {
this.type = type;
}
public void runCar() {
if (type == CarType.Ford) {
fcar.run();
} else {
hcar.run();
}
}
public void turnCar() {
if (type == CarType.Ford) {
fcar.turn();
} else {
hcar.turn();
}
}
public void stopCar() {
if (type == CarType.Ford) {
fcar.stop();
} else {
hcar.stop();
}
}
}
/**
* @author【蝉沐风】
* @desc 自动驾驶系统
*/
public class AutoDriver {
public enum CarType {
Ford, Honda, Audi, Benz, Bmw
}
private CarType type;
private HondaCar hcar = new HondaCar();
private FordCar fcar = new FordCar();
private AudiCar audicar = new AudiCar();
private BenzCar benzcar = new BenzCar();
private BmwCar bmwcar = new BmwCar();
public AutoDriver(CarType type) {
this.type = type;
}
public void runCar() {
if (type == CarType.Ford) {
fcar.run();
} else if (type == CarType.Honda) {
hcar.run();
} else if (type == CarType.Audi) {
audicar.run();
} else if (type == CarType.Benz) {
benzcar.run();
} else {
bmwcar.run();
}
}
public void turnCar() {
if (type == CarType.Ford) {
fcar.turn();
} else if (type == CarType.Honda) {
hcar.turn();
} else if (type == CarType.Audi) {
audicar.turn();
} else if (type == CarType.Benz) {
benzcar.turn();
} else {
bmwcar.turn();
}
}
public void stopCar() {
if (type == CarType.Ford) {
fcar.stop();
} else if (type == CarType.Honda) {
hcar.stop();
} else if (type == CarType.Audi) {
audicar.stop();
} else if (type == CarType.Benz) {
benzcar.stop();
} else {
bmwcar.stop();
}
}
}
- 高层模块(high-level modules)不要直接依赖低层模块(low-level);
- 高层模块和低层模块应该通过抽象(abstractions)来互相依赖;
- 抽象(abstractions)不要依赖具体实现细节(details),具体实现细节(details)依赖抽象(abstractions).
AutoDriver
XXCar
AutoDriver
new

ICar
AutoDriver
ICar
/**
* @author【蝉沐风】
* @desc 汽车的抽象接口
*/
public interface ICar {
void run();
void turn();
void stop();
}
public class FordCar implements ICar{
@Override
public void run(){
System.out.println("福特开始启动了");
}
@Override
public void turn(){
System.out.println("福特开始转弯了");
}
@Override
public void stop(){
System.out.println("福特开始停车了");
}
}
public class HondaCar implements ICar{
@Override
public void run() {
System.out.println("本田开始启动了");
}
@Override
public void turn() {
System.out.println("本田开始转弯了");
}
@Override
public void stop() {
System.out.println("本田开始停车了");
}
}
public class AudiCar implements ICar{
@Override
public void run() {
System.out.println("奥迪开始启动了");
}
@Override
public void turn() {
System.out.println("奥迪开始转弯了");
}
@Override
public void stop() {
System.out.println("奥迪开始停车了");
}
}
public class BenzCar implements ICar{
@Override
public void run() {
System.out.println("奔驰开始启动了");
}
@Override
public void turn() {
System.out.println("奔驰开始转弯了");
}
@Override
public void stop() {
System.out.println("奔驰开始停车了");
}
}
public class BmwCar implements ICar {
@Override
public void run() {
System.out.println("宝马开始启动了");
}
@Override
public void turn() {
System.out.println("宝马开始转弯了");
}
@Override
public void stop() {
System.out.println("宝马开始停车了");
}
}
/**
* @author【蝉沐风】
* @desc 自动驾驶系统
*/
public class AutoDriver {
private ICar car;
public AutoDriver(ICar car) {
this.car = car;
}
public void runCar() {
car.run();
}
public void turnCar() {
car.turn();
}
public void stopCar() {
car.stop();
}
}
AutoDriver
ICar
XXXCar
AutoDriver
ICar
XXXCar
ICar
AutoDriver
ICar

AutoDriver
XXXCar
AutoDriver
ICar
XXXCar
ICar
3.3 无所不在的抽象
3.3.1 JVM的抽象
3.3.2 货币的诞生
边栏推荐
猜你喜欢
Multi-scalar multiplication: state of the art & new ideas
AI引领一场新的科学革命
[Raspberry Pi] vim editor
【office】word
The keys of the Flutter storage database
Offensive and defensive world - web2
攻防世界——leaking
Techwiz OLED:偏振片的发射特性
22-08-06 Xi'an EasyExcel implements dictionary table import and export
Offensive and defensive world - leaking
随机推荐
机器学习理论及案例分析(part3)--聚类
Do you really know IP addresses?
The entity List to excel
斯坦福21秋季:实用机器学习【第5章】
mysql-cdc 换2.2.x 版本 怎么读不到 数据 咋回事
数据库调优:Mysql索引对group by 排序的影响
AI引领一场新的科学革命
docker部署redis容器问题
让百姓消费更安全更放心更满意 江苏出台放心消费创建示范认定管理办法
简单理解MVVM模型
X射线聚焦系统
代码检查工具
Raspberry pie 】 【 without WIFI even under the condition of the computer screen
shell脚本知识记录
LVS负载均衡群集及NAT模式群集
VPP source address NAT
Multi-scalar multiplication: state of the art & new ideas
开源一夏|Flutter实现搜索的三种方式
一个用来装逼的利器
Offensive and defensive world - leaking