likes
comments
collection
share

TypeScript依赖注入与控制反转

作者站长头像
站长
· 阅读数 20

为什么要用依赖注入与控制反转

当我们需要实现类之间的相互依赖的时候,如果按照一般的写法,当我们需要更改A类中的信息时,此时需要同时在B、C两个类进行修改,多个类之间有着强耦合的关系,这在代码量不大的时候可能不是什么大问题,但是当工程大起来就是个非常费力的事情。

// 强耦合
class A{
    name:string
    constructor(name:string){
        this.name = 'Ccat'
    }
}

class B{
    a:any
    constructor(){
        this.a = new A('Ccat').name
    }
}

class C{
    a:any
    constructor(){
        this.a = new A('Ccat').name
    }
}

什么是依赖注入与控制反转

控制反转(Inversion of Control,简称IoC),是面向对象编程中的一种设计原则,用于降低代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。他们二者的关系为:依赖注入是控制反转的实现形式之一。

看起来这个定义有些抽象,我们需要关注其中的几个关键词

  1. 控制:我们需要关注是谁控制了谁。在传统面向对象编程中我们通过在对象内部通过new进行创建对象,程序主动去创建依赖对象。而在控制反转模式下,是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
  2. 反转:反转是由容器来帮忙创建及注入依赖对象。因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

可以理解成我们将所有需要用到的类统一放在一个容器中进行发布,其他类可以通过类似订阅的方式获取到容器中提前注入好的类。(仅仅是类似,还是有部分差异的)

如何在Ts中实现依赖注入与控制反转

我们在Ts中可以通过创建一个Container类作为IoC容器,其中定义一个module对象用于放置收集好的依赖。该类中的provide方法用于收集依赖的注入,并将收集到的依赖注入至这个类的module对象中。同时设置get方法供其他类获取module对象中已经注入的依赖

class A{
    name:string
    constructor(name:string){
        this.name = name
    }
}

class C{
    name:string
    constructor(name:string){
        this.name = name
    }
}

//中间件用于收集依赖,实现解耦
class Container{
    module:any
    constructor(){
        this.module = {}
    }

    // 依赖注入
    provide(key:string,mo:any){
        this.module[key] = mo
    }

    // 取引用
    get(key:string){
        return this.module[key]
    }
}

const mymo = new Container()
mymo.provide('a',new A('我是A类!!'))
mymo.provide('c',new A('我是C类!!'))

class B{
    a:any
    c:any
    constructor(mo:Container){
        this.a = mo.get('a').name

        this.c = mo.get('c').name
    }
}

const myB = new B(mymo)
console.log("B类的a为"+myB.a)
console.log("B类的c为"+myB.c)

于是我们实现了一个简单的依赖注入与控制反转的Demo,这段Ts代码执行以后的结果为:

TypeScript依赖注入与控制反转