元编程
定义
狭义来说,应该是指「编写能改变语言语法特性或者运行时特性的程序」。换言之,一种语言本来做不到的事情,通过你编程来修改它,使得它可以做到了,这就是元编程。
在 ES6 中的体现
从这个角度来看,Proxy、Reflect是js的元编程。并且装饰器中,为类方法的参数设置要求(类型、是否必须)等都是元编程,因为js本身或者ts本身(只能声明类型、不能校验或者转化)都做不到,通过编码做到了。
Proxy:可以改变对象的默认行为。例如可以拦截对象的读、写等操作。
Reflect:反射,可以获取元信息。配合 reflect-metadata,更加强壮。例如可以在对象未实例化时,在对象外部,获取构造函数参数类型、方法参数类型、属性类型。
更多资料
控制反转(IoC)
控制反转是面向对象编程中的一种原则,用于降低代码之间的耦合度。
传统方法:在类的内部主动创建依赖对象,这样将导致类与类之间耦合度非常高,并且不容易测试。
1 | import { ModuleA } from './module-A'; |
控制反转:将创建和查找依赖对象的控制权交给了IoC容器,这样对象与对象之间就是松散耦合了,方便测试与功能复用
1 | // 文件1:container.js |
此时,对于ModuleC来说,可以对接不同的容器,而不同容器中的ModuleA和ModuleB各不相同,相比于传统方法,可以做到在不改动ModuleC的情况下,实现不同类的注入。
同理,对于测试来说,可以mock ModuleA和mock ModuleB,将测试的点聚焦于ModuleC本身的逻辑。
依赖注入(DI)
依赖注入是控制反转最常见的一种应用方式(或者实现方法),即通过控制反转,在对象创建的时候,自动注入一些依赖对象。
在TS中,使用装饰器和元编程,可以实现依赖注入。看看NestJS中DI的写法:
1 | import { Injectable } from '@nestjs/common'; |
实现原理请看: NestJS源码:实现依赖注入(DI)