【momo·走向全栈】浅析Nest.js的IOC实现

139 阅读4分钟

前言:作为一个正在找实习的大三学子,为了让简历看起来更加nice,我进行了JS的后端框架的学习。由于Nest.js霸气的logo以及前段时间校园项目负责人的经历对Spring系列的学习,我对Nest.js有所偏爱。于是,故事开始了......

  插曲,在进行本篇写作前,我写过一份简历,当我写到Nest的时候我写的是AOP但是我想表达的是IOC,丢大脸!所以希望大伙能对相关的概念有所熟悉并进行区分,毕竟咱也不能只是当个业务仔、切图仔,但是别将其奉到神坛,毕竟在我们的代码世界俺们才是创造者。
  受限于作者水平,本文会浅析Nest.js和Spring的IOC实现,并用小的篇幅描述AOP。

AOP

  AOP面向切面编程。在服务器端开发的时候,分层的思想贯彻了开发的整个开发的周期。在对系统进行开发的时候,我们希望把非业务逻辑代码从业务逻辑中进行分离出来,封装到独立的模块中,能实现这些模块的功能但是又不影响业务逻辑代码。这时候我们希望有一个切面能将模块进行包容,这就是我理解的面向切面编程AOP
  通常,切面影响的功能有日志记录性能统计安全控制。对于Nest.js中对AOP的体现,可以参考神光大佬的文章
  如下图所示,其实对于用户而言效果是一样的,但是分出切面进行维护逻辑更加鲜明! 未命名文件 (45).png

IOC

简介

  IOC(Inversion of Control)控制反转是面向对象编程的一种设计模式,主要用于降低代码的耦合性,减少代码的依赖关系,通常会使用“依赖注入”“依赖查找”的方式进行对IOC的实现。市面上部分常见的服务器端框架都对其进行了实现。首先作者水平下面将对Nest.jsSpring的IOC实现进行浅析。

Nest.js的IOC实现

  Nest.js的IOC是基于装饰器模式进行实现,其中装饰器模式ES7中已经进行了提案,而Babel已经支持。目前项目创建的时候,只要对其进行解开相关的注释就能体验其功能。下面让我们对代码分别使用装饰器模式和平时的实现进行对比。
当js不使用适配器模式的话:
image.png
当原生js遇到适配器:

image.png
当工程中遇上了装饰器模式:
准备工作:

  1. tsc --init
  2. 如图所示,进入tsconfig.json并且解开装饰器模式 image.png
    正式工作:
      在Nest.js中IOC是靠着ES7实验属性experimentalDecorators封装出属性装饰器参数装饰器方法装饰器类装饰器进行实现,下面是对其的测试demo。
/**
 * 类装饰器
 * declare type ClassDecorator =  <TFunction extends Function>(target: TFunction) => TFunction | void;
 */
const decotator:ClassDecorator = (target:any) => {
    target.prototype.name = '测试IOC'
}
/**
 * 属性装饰器
 * declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
 */
const decotatorProperty: PropertyDecorator = (target: any, key: string | symbol)=>{
    console.log(target,key);
}

/**
 * 方法装饰器
 * declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
 */

const decotatorsMethord: MethodDecorator = (target: Object, propertyKey: string | symbol, descriptor: any)=>{
    console.log(target,propertyKey,descriptor);
}

/**
 * 属性装饰器
 * declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;
 */
const parm : ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number)=>{
    console.log(target,propertyKey,parameterIndex);
}

@decotator
class IOCTest {
   @decotatorProperty
   private age : number
   @decotatorsMethord
   sayHello(@parm name:string){
        console.log("Hello!"+name);
   }
    constructor (age:number) {
        this.age = age
    }
}
 
const test:any = new IOCTest(20)
console.log(test.name)
console.log(test.age)

image.png

和spring中的IOC对比

  本来是没想着进行对比的,因为我用@命令(参数)的形式对二者单论使用是无感的,直到看到神光大佬文章下的zhoucheng大佬对其进行对比,我也收获丰富。
  java中流行的对IOC的实现形式有注解xml文件两种但是归根到底应用的还是反射动态代理

image.png

  由于笔者水平受限,目前还不能提供spring的IOC实现原理的demo,如果有了解的饱饱,欢迎私信或者在评论区交流,momo不胜感激!
  Nest的语法非常自由,希望你也能一起学习这款IOC框架!

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情