NestJS之00-基础知识

323 阅读3分钟

1. 基础知识

IOC(Inversion of Control,控制反转)是一种设计模式,它的主要思想是将控制权交给一个中央的框架或容器,由容器负责调用和管理创建好的对象,而不是由代码本身负责直接调用和管理这些对象。这样可以使得代码更加灵活、可扩展和可维护,降低代码的耦合性和复杂性,提高代码的可测试性和可读性。

IOC模式的核心是将对象之间的依赖关系通过配置文件或注解等方式进行解耦,从而实现了一种松耦合的设计方式,促使了系统的灵活性和可扩展性。Spring框架就是一个典型的应用IOC模式的框架,它的核心是IOC容器和DI(Dependency Injection,依赖注入)功能,可以实现自动装配和对象管理等功能。

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


class B {
    age: number
    entry: A
    constructor(age: number) {
        this.age = age
        this.entry = new A('哈哈哈 强耦合')
    }
}

const b = new B(18)
console.log(b.entry.name)

image.png

使用IoC容器和DI

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

//中间件用于解耦
class Container{
    modules:any
    constructor() {
            this.modules = {}
    }
    provide(key: string, module: any) {
            this.modules[key]=module
    }

    get(key:string) {
            return this.modules[key]
    }
}


const container = new Container()
// 依赖注入
container.provide('a', new A('jack'))

// 定义B的使用类
class B {
    a: any
    constructor(container: Container) {
            this.a = container.get('a')
    }
}

const b = new B(container) 
console.log(b.a.name)

image.png

这段代码是一个简单的手动装配方式的IoC容器,它使用了IoC和DI的思想。其中,Container类用于解耦模块之间的依赖关系,它提供了provide方法来维护模块和对应的关键字之间的映射,同时提供了get方法来获取对应的模块实例。B类通过Container类注入了A类的实例,实现了B类对A类的依赖注入。

2. ts装饰器

TypeScript的类装饰器可以被看作是一种AOP(Aspect-Oriented Programming,面向切面编程)的编程思想。

AOP的设计理念是通过预处理和后处理实现对程序代码的横向切割,将原本分散的重要功能统一管理,这些重要功能称为“切面(Aspect)”。具体来说,AOP的作用是将那些与核心业务逻辑相互交织的支持性代码(例如日志记录、性能统计、安全控制、事务处理等)通过“横向抽取”封装到一个或多个切面中,从而使得核心业务逻辑更加清晰、简洁。

在TypeScript中,类装饰器就是一种实现AOP编程思想的方式。类装饰器可以用来在类定义、实例化或方法调用时对类和类的成员(属性和方法)进行修饰和包装,从而实现对类行为进行增强或横向抽取的目的。其作用与Java中的注解和C#中的特性类似。

// 开启装饰器
"experimentalDecorators": true,  

// 类装饰器
const classDec: ClassDecorator = (target: any) => {
    console.log('打印***target', target)
    target.prototype.age = 18
}

// 属性装饰器
const propertyDec: PropertyDecorator = (target: Object, key: string | symbol) => {
    // {} name
    console.log(target, key)
}

// 方法装饰器
const methodDec: MethodDecorator = (target: Object, key: string | symbol, descriptor: any) => {
    // {} 方法名称 描述符
    // {
    //   value: [Function: getName],
    //   writable: true,
    //   enumerable: false,
    //   configurable: true
    // }
    console.log(target, key, descriptor)
}

// 参数装饰器
const parameterDec: ParameterDecorator = (target: Object, key: string | symbol, index: any) => {
    //{} getName 函数名称 0 index是参数所在位置
    console.log(target, key, index)
}

/** 如何传参数 不破环原有类 */
@classDec
class Desc {
    @propertyDec
    public name: string

    constructor() {
            this.name = '属性装饰器'
    }

    @methodDec
    getName(@parameterDec age: number) {
            return this.name
    }
}

const desc: any = new Desc()

console.log(desc.name)

3. 写一个axios的请求

安装 npm i axios -S

import axios from 'axios'

const Get = (url: string): MethodDecorator => {
    return function (target: object, key: string | symbol, descriptor: PropertyDescriptor) {
        //value: [Function: getList],
        console.log('打印***descriptor,url', descriptor, url)
        // 获取getList方法 将结果以回调的形式传递,方法可以直接得到结果
        const originGetList = descriptor.value
        axios
                .get(url)
                .then(res => {
                        originGetList(res, { code: 1 })
                })
                .catch(e => {
                        originGetList(e, { code: 0 })
                })
	}
}

class Controller {
    constructor() {}

    @Get('https://api.apiopen.top/api/getHaoKanVideo?page=0&size=10')
    getList(res: any, code: any) {
            console.log('打印***res,code', res, code)
            return res.data
    }
}

image.png

image.png


参考文章视频来源

主要是自己学习记录一下,并不是完全copy。

nestjs学习视频小满B站

小满CSDN笔记