门面模式(Facade Pattern)是一种结构型设计模式,通过提供统一接口简化对复杂子系统的访问,隐藏子系统内部细节,使客户端代码更易用。
设计模式原理
门面模式通过为复杂子系统提供单一入口点,屏蔽内部实现细节。客户端只需与门面交互,无需直接操作子系统。
结构概述
- Facade(门面) :定义高层次接口,协调子系统操作。
- Subsystem Classes(子系统类) :实现具体业务逻辑。
- Client(客户端) :通过门面调用子系统功能。
优点
- 简化接口:降低客户端与子系统的耦合,减少学习成本。
- 松耦合:子系统变化不影响客户端代码。
- 可维护性:隔离子系统逻辑,便于测试和修改。
- 分层架构:适合Nest.js模块化设计,封装复杂交互。
适用场景
- 简化多服务交互(如用户注册涉及用户管理、邮件发送)。
- 隐藏框架或库的复杂实现。
- 构建统一API入口,提升代码一致性。
Nest.js框架源代码分析:门面模式的应用
在Nest.js中,NestFactory
和NestApplication
共同体现了门面模式。NestFactory
作为静态工厂类,负责创建NestApplication
实例,而NestApplication
作为核心门面,封装了应用初始化、HTTP服务器管理和依赖注入等复杂逻辑,为开发者提供简化的接口。
NestFactory 和 NestApplication 的关系
NestFactory
:位于packages/core/src/nest-factory.ts
,是一个静态工厂类,负责创建和配置NestApplication
实例。它通过create
方法初始化应用,设置HTTP适配器(如Express或Fastify)并返回NestApplication
对象。NestFactory
本身不处理运行时逻辑,而是充当配置和初始化的入口。NestApplication
:位于packages/core/src/application/nest-application.ts
,是运行时的核心门面,管理模块解析、HTTP服务器启动和依赖注入等功能。开发者通过NestApplication
的init()
和listen()
方法操作应用,而无需了解底层细节。
NestFactory
和NestApplication
的协作类似于门面模式的客户端和门面关系:NestFactory
为开发者提供创建应用的简单接口,而NestApplication
隐藏了复杂的子系统交互(如模块加载、依赖注入)。
代码示例
NestFactory 源码(简化摘录)
typescript
// packages/core/src/nest-factory.ts
import { NestApplication } from './application/nest-application';
import { HttpAdapterHost } from './adapters/http-adapter-host';
import { Module } from './injector/module';
import { NestApplicationOptions } from './interfaces';
export class NestFactory {
public static async create(
module: any,
options?: NestApplicationOptions,
): Promise<NestApplication> {
const httpAdapter = new HttpAdapterHost(options?.httpAdapter);
const app = new NestApplication(new Module(module), httpAdapter, options);
await app.init();
return app;
}
}
NestApplication 源码(简化摘录)
typescript
// packages/core/src/application/nest-application.ts
import { INestApplication, NestApplicationOptions } from './interfaces';
import { Module } from '../injector/module';
import { HttpAdapterHost } from '../adapters/http-adapter-host';
import { Injector } from '../injector';
export class NestApplication implements INestApplication {
constructor(
private readonly module: Module,
private readonly httpAdapterRef?: HttpAdapterHost,
private readonly options?: NestApplicationOptions,
) {
this.injector = new Injector();
this.initialize();
}
public async init(): Promise<this> {
// 初始化模块、绑定适配器等
await this.callInitHooks();
await this.callBootstrapDoneHook();
return this;
}
public listen(port?: number, hostname?: string, callback?: () => void): Promise<this> {
// 简化HTTP服务器启动
return this.httpAdapterRef.httpAdapter.listen(port, hostname, callback);
}
public get<T = any>(name: string | symbol | Type<T>, options?: GetOrResolveOptions<T>): T {
// 统一依赖访问
return this.injector.get(name, options);
}
}
运行结果
在main.ts
中,开发者通过NestFactory
创建并启动应用:
typescript
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule); // 使用NestFactory创建NestApplication
await app.listen(3000); // 调用NestApplication的listen方法启动服务器
}
bootstrap();
总结
门面模式通过NestFactory
和NestApplication
在Nest.js中得到完美体现。NestFactory
作为创建应用的门面,简化了初始化流程;NestApplication
作为运行时门面,封装了模块管理、HTTP服务器和依赖注入等功能。开发者只需调用简单接口即可操作复杂系统,门面模式确保了代码的简洁性、可维护性和模块化,适合构建大型Nest.js应用。