依赖反转
依赖反转是SOLID设计原则中的最后一个原理,Dependency Inversion
。其核心的目的是减少模块与模块之间的耦合,提高代码的可维护性和扩展性。
依赖反转的关键点:
- 模块之前不应该存在直接的依赖关系,两者都应该依赖于抽象类或者接口
- 抽象不应该依赖于细节,细节需要依赖于抽象
下面以Node.js来举例,假设有一个UserSerivce类,需要从数据库中来查询用户信息,如果没有应用依赖反转,那么UserSerivce类需要依赖于数据库,这样会导致UserSerivce类与数据库耦合,如果数据库发生变化,那么UserSerivce类也需要跟着变化,这显然是不合理的。
class UserService {
constructor(db) {
this.db = db;
}
getUser(id) {
return this.db.getUser(id);
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
下面利用依赖反转来重构以上代码:
// IUserRepository.ts
abstract class IUserRepository {
getUser(id) {
throw new Error('not implemented');
}
}
// UserRepository.ts
class UserRepository extends IUserRepository {
constructor(db) {
super();
this.db = db;
}
getUser(id) {
return this.db.getUser(id);
}
}
// UserSerivce.ts
class UserSerivce {
constructor(userRepository) {
this.userRepository = userRepository;
}
getUserInfo(id) {
return this.userRepository.getUser(id);
}
}
//app.ts
const Db = require('./db');
const UserRepository = require('./UserRepository');
const UserService = require('./UserService');
const db = new Db()
const userRepository = new UserRepository(db);
const userService = new UserService(userRepository);
userService.getUserInfo(1);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
通过这种依赖反转的方式,如果我们需要增加缓存或者是更换数据库技术,那么只需要重新实现一个IUserRepostory即可,UserServicelei本身不需要与存储细节耦合。
Last Updated: 2024/01/08, 19:49:22