当前位置:网站首页>「控制反转」和「依赖倒置」,傻傻分不清楚?
「控制反转」和「依赖倒置」,傻傻分不清楚?
2022-08-08 09:11: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 货币的诞生
边栏推荐
- 67:第五章:开发admin管理服务:20:开发【解冻/冻结用户,接口】;(用户状态变更后,需要刷新用户状态,即变更用户会话信息:我们一般通过“删除redis中会话信息,强制用户重新登录“来做的;)
- To make people's consumption safer, more assured and more satisfied
- AI引领一场新的科学革命
- VPP源地址NAT
- VPP静态映射实现DNAT
- oracle中联表相关思考
- 记一次生产内存溢出分析解决
- 交换两个整型变量的三种方法
- 你一定要看的安装及卸载测试用例的步骤及方法总结
- Multi-scalar multiplication: state of the art & new ideas
猜你喜欢
Defense - MFW all over the world
中原银行实时风控体系建设实践
LAN技术-5Eth-Trunk
Raspberry pie 】 【 without WIFI even under the condition of the computer screen
HTTS 为什么更安全?
COMSOL Multiphysics 6.0 software installation package and installation tutorial
Excel method is commonly used in text function 5
推荐100首好听英文歌
字节与字符与常见编码方式
ES8 | async and await
随机推荐
.json()的使用
【收藏】3. 壁纸收藏
干货 | Oracle数据库操作命令大全,满满的案例供你理解,收藏!
巧用Prometheus来扩展kubernetes调度器
【office】word
DVWA全级别详细通关教程
数学基础(二)逆矩阵、伪逆矩阵、最小二乘解、最小范数解
Database Tuning: The Impact of Mysql Indexes on Group By Sorting
VPP source address NAT
在数学里,minimum 和 minimal 有啥区别吗?
Is it safe to buy stocks with a straight flush?Will the funds be transferred?
Web优化躬行记(6)——优化闭环实践
mysql-cdc 换2.2.x 版本 怎么读不到 数据 咋回事
22-08-06 Xi'an EasyExcel implements dictionary table import and export
ACWing 198. 反素数 题解
写在 26 岁生日
英文token预处理,用于将英文句子处理成单词
The entity List to excel
Offensive and defensive world - web2
攻防世界——fakebook