Skip to content

Commit 6ac311f

Browse files
authored
Merge pull request #127 from GuoXiCheng/dev-c
update
2 parents dc0f5c0 + 716d439 commit 6ac311f

1 file changed

Lines changed: 87 additions & 2 deletions

File tree

src/interview.md

Lines changed: 87 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,93 @@
1616
// [!code focus]
1717

1818
装饰器其实就是一个函数,它可以用在类、方法或者属性上,来扩展它们的功能。
19-
2019
比如我可以用它来做日志记录、权限控制,或者缓存一些中间结果。
21-
2220
它的最大优点是能把跟业务无关的代码从核心逻辑里抽离出来,这样代码更清晰简洁、也更好维护。
2321
```
22+
23+
## 说说你对依赖注入的理解
24+
25+
```java
26+
// [!code focus]
27+
28+
我理解的依赖注入,其实就是说,当一个服务需要用到其他组件的时候,
29+
它自己不负责创建这些依赖,而是由外部把这些依赖传进来。
30+
31+
举个例子,比如我有一个服务要用数据库对象。
32+
如果我在服务里直接 new 一个数据库对象,那这个服务就跟这个数据库实现耦合得很死。
33+
34+
但如果我通过构造函数把数据库对象传进来,我就可以自由替换这个依赖,
35+
比如在写单元测试时用一个内存数据库或者 mock 对象来替代。
36+
37+
这样做的好处是,耦合度低、职责清晰,而且特别适合测试,能让代码更灵活、可维护性更强。
38+
```
39+
40+
## 你是否自己实现过简化版的依赖注入容器
41+
42+
```java
43+
// [!code focus]
44+
45+
我会先创建一个Map作为容器对象,用来保存服务的构造函数或实例。
46+
47+
然后提供一个register方法注册服务,一个resolve方法创建实例,
48+
resolve方法会自动查找构造函数的参数,递归地实例化依赖。
49+
```
50+
51+
简化版依赖注入容器
52+
53+
```typescript
54+
class Container {
55+
private providers = new Map();
56+
57+
register(token: any, provider: any) {
58+
this.providers.set(token, provider);
59+
}
60+
61+
resolve(token: any): any {
62+
const Provider = this.providers.get(token);
63+
const deps = Reflect.getMetadata("design:paramtypes", Provider) || [];
64+
const instances = deps.map((dep: any) => this.resolve(dep));
65+
return new Provider(...instances);
66+
}
67+
}
68+
```
69+
70+
进阶版带装饰器的依赖注入容器
71+
72+
```typescript
73+
import "reflect-metadata";
74+
75+
class Container {
76+
private providers = new Map();
77+
78+
register(token: any) {
79+
this.providers.set(token, token);
80+
}
81+
82+
resolve<T>(token: new (...args: any[]) => T): T {
83+
const target = this.providers.get(token);
84+
const deps = Reflect.getMetadata("design:paramtypes", target) || [];
85+
const instances = deps.map((dep: any) => this.resolve(dep));
86+
return new target(...instances);
87+
}
88+
}
89+
90+
// 装饰器:用于自动注册类
91+
function Injectable(target: any) {
92+
container.register(target);
93+
}
94+
```
95+
96+
```typescript
97+
const container = new Container();
98+
99+
@Injectable
100+
class DatabaseService {}
101+
102+
@Injectable
103+
class UserService {
104+
constructor(private db: DatabaseService) {}
105+
}
106+
107+
const userService = container.resolve(UserService);
108+
```

0 commit comments

Comments
 (0)