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

还是Angular官网讲的清楚
依赖注入 - ts - GUIDE

依赖注入

有一个函数,在实现的时候需要依赖其他函数一起作用,来实现完整功能,例如:

function returnRandom () {
    return 1;
}

function returnUserName () {
    return 'TEST';
}

/** main函数依赖returnRandom和returnUserName来实现功能 */
function main () {
    const random = returnRandom();
    const userName = returnUserName();
    return random + userName;
}

main();

        此时main函数和returnRandom、returnUserName紧密耦合,当returnRandom需要传入一个参数时(即函数实现出现变更时)main函数的实现也需要变更,尤其是当这个参数需要从main接收再传入到returnRandom时,代码的变更变得更加复杂、容易出错。

function returnRandom (param) {
    return 1 + param;
}

function returnUserName () {
    return 'TEST';
}

/** main函数依赖returnRandom和returnUserName来实现功能 */
function main (param) {
    const random = returnRandom(param);
    const userName = returnUserName();
    return random + userName;
}

main(Math.random());

        当returnRandom和returnUserName不在main函数内部实现,而是作为参数传入main函数时,main、returnRandom、returnUserName就解耦了,main的实现不再依赖returnRandom和returnUserName。

function returnRandom () {
    return 1;
}

function returnUserName () {
    return 'TEST';
}

function main (random, userName) {
    return random + userName;
}

main(returnRandom(), returnUserName());

        returnRandom和returnUserName的实现变更时,不会影响到main的实现。

function returnRandom (param) {
    return 1 + param;
}

function returnUserName (nickName) {
    return 'TEST' + nickName;
}

function main (random, userName) {
    return random + userName;
}

main(returnRandom(Math.random()), returnUserName('nickName'));

         这就是依赖注入,逻辑的实现有外部依赖时,将依赖通过外部传入的方式注入,而非在逻辑内部直接定义并使用外部依赖,这有助于代码的解耦和测试。为什么有助于测试呢?因为现在我们对它的依赖有了完全的控制权,我们可以直接创建一些mock数据测试逻辑。如果未使用依赖注入,我们可能需要使用一些难以维护的方式来测试逻辑(例如注释代码实现后填入mock数据,测试完成后再还原代码)。

function returnRandom (param) {
    return 1 + param;
}

function returnUserName (nickName) {
    return 'TEST' + nickName;
}

function main (random, userName) {
    return random + userName;
}

/** 原代码实现 */
main(returnRandom(Math.random()), returnUserName('nickName'));

/** 当你需要测试main函数时 */
const mockRandom = NaN;
const userName = null;
main(mockRandom, userName);

控制反转

         使用依赖注入后,代码优雅解耦,但是这对于编写和阅读代码的人来说就有点痛苦了,尤其是依赖多、依赖复杂的情况下,代码变得难以阅读。那我们能不能让依赖注入这件事自动完成?这就要使用控制反转了:借助于“第三方”实现具有依赖关系的对象之间的解耦。

        简单来说就是把一些事交给框架来做,例如react、vue实现的更新机制,在数据变更时自动对真实dom进行最小化的更改,而没有控制反转的话,我们就需要使用vanilla js、jquery,在数据变更的同时,手动地查找dom、拼接数据、更新dom。

        依赖注入也是可以如此,使用者只需要在代码中定义想要注入的依赖,由框架层完成依赖的创建、注入。具体实现不描述,很多库有示例:

@Injectable
class Food {}

@Injectable
class Bark {}

/** Eat依赖Food */
@Injectable
class Eat {
    constructor (private food: Food) {}
}

/** Dog依赖Bark和Eat */
@Injectable
class Dog {
    /** 定义需要的依赖,由框架层自动注入 */
    constructor (private eat: Eat, private bark: Bark) {}

    wantSomeFood () {
        this.bark.call();
    }
}

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值