【7.27】依赖注入(DI)&控制反转(IOC)

882 阅读2分钟

what is Inversion of Control(IOC)

如果没有控制反转的话,一个软件系统中的对象可能会互相耦合,对象之间的依赖关系十分复杂么,牵一发动全身,像下面图的齿轮一样

image.png

对于这种耦合度过高的问题,有一种设计原则是控制反转,通过第三方来做依赖关系之间的解耦

image.png

通过中间的第三方,让 ABCD 四个对象没有了耦合关系,他们之前的依赖传递完全交给了第三方来做

但是为什么叫控制反转呢,因为之前如果在 A 中想要初始化对象 B,不管是自己创建还是使用已有的对象 B,控制权完全在 A 上。

使用了控制反转之后,在 A 需要用 B 的时候,loc 容器会主动创建一个对象 B 到 A 需要的地方

这个就是控制反转,A 需要 B,从 A 主动去 new 变成了一个被动的行为,控制权颠倒了,由 loc 框架去控制了

在生活中也会有这样的例子:

比如部门去对接多个客户做ppt,每个客户做的时候,都需要专人跟进,定义一种新的类型,当业务越做越大,单独去对接各个客户已经很麻烦了,严重依赖客户提供的内容。所以部门制定了一个ppt制作规范,开发了一个ppt校验的系统,只有符合这些规范的才可以接入,使控制反转到了部门这一方。

what is dependency injection(DI)

将依赖之间解耦,这样做的好处是:

1.将依赖之间解耦

2.方便做单元测试,尤其是 mock 测试,实例可以传入

依赖注入是控制反转(IoC - Inversion of Control)设计模式的一种实现方式,控制反转还有其他的实现方式,比如 ServiceLocator,于是他们是不对等的

nodejs 框架实现依赖注入的方式

以 typedi 为例,通过 @Service 和 @Container 将 class 或者自定义的字符串注入到 loc 容器中,通过 @Inject 方式可以自动推断属性的类型,将实例赋给对应的属性;或者使用 Container.get 的方式从容器中拿到实例。

import 'reflect-metadata';
import { Container, Inject, Service } from 'typedi';

@Service()
class InjectedExampleClass {
    print() {
        console.log('I am alive!');
    }
}

@Service()
class ExampleClass {
    @Inject()
    withDecorator: InjectedExampleClass;
    withoutDecorator: InjectedExampleClass;
}

const instance = Container.get(ExampleClass);

/**
* The `instance` variable is an ExampleClass instance with the `withDecorator`
* property containing an InjectedExampleClass instance and `withoutDecorator`
* property being undefined.
*/
console.log(instance);
instance.withDecorator.print();
// prints "I am alive!" (InjectedExampleClass.print function)
console.log(instance.withoutDecorator);
// logs undefined, as this property was not marked with an @Inject decorator

根据这个文章学习的,推荐:www.jianshu.com/p/07af9dbbb… docs.typestack.community/typedi/02-b…