面试题答案
一键面试基于服务功能的模块划分与架构设计
- 按业务功能划分模块
- 将相关的服务归为同一个模块,例如用户管理相关的服务(如用户登录、注册、信息更新等服务)可以放在
user - module
中。这样当需要修改或扩展用户相关功能时,所有相关代码都集中在一个模块,方便维护和查找。 - 示例:
- 将相关的服务归为同一个模块,例如用户管理相关的服务(如用户登录、注册、信息更新等服务)可以放在
// user - module.ts
import { NgModule } from '@angular/core';
import { UserLoginService } from './user - login.service';
import { UserRegisterService } from './user - register.service';
@NgModule({
providers: [UserLoginService, UserRegisterService]
})
export class UserModule {}
- 共享模块
- 对于一些通用的服务,如日志记录、网络请求等服务,可以创建一个共享模块
shared - module
。这样多个业务模块都可以复用这些服务,避免代码重复。 - 示例:
- 对于一些通用的服务,如日志记录、网络请求等服务,可以创建一个共享模块
// shared - module.ts
import { NgModule } from '@angular/core';
import { LoggerService } from './logger.service';
import { HttpService } from './http.service';
@NgModule({
providers: [LoggerService, HttpService],
exports: []
})
export class SharedModule {}
- 功能隔离
- 确保每个模块的服务功能相对独立,减少模块之间的耦合。比如,订单模块的服务不应该直接依赖于库存模块的内部实现细节,而应该通过定义良好的接口进行交互。
- 示例:
// order - module.ts
import { NgModule } from '@angular/core';
import { OrderService } from './order.service';
import { InventoryService } from '../inventory/inventory.service';
// OrderService 通过接口使用 InventoryService 的功能
export interface InventoryInterface {
checkStock(productId: number): boolean;
}
@NgModule({
providers: [OrderService]
})
export class OrderModule {}
使用 Angular 特性优化服务调用性能与加载时间
- 懒加载模块
- 策略:将不常用或较大的模块设置为懒加载。这样在应用启动时,这些模块不会立即加载,只有在需要时才会加载,从而减少初始加载时间。
- 示例:
- 在
app - routing.module.ts
中配置懒加载模块:
- 在
const routes: Routes = [
{
path: 'admin',
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
}
];
- 这里 `admin` 模块是懒加载的,当用户访问 `/admin` 路由时,`AdminModule` 及其相关的服务才会被加载。
2. 依赖注入的高级特性
- 使用 @Injectable({ providedIn: 'root' }):
- 策略:对于一些全局单例的服务,可以在服务类上使用 @Injectable({ providedIn: 'root' })
语法糖。这样 Angular 会在根模块自动提供该服务,并且保证整个应用中只有一个实例,避免重复创建服务实例带来的性能开销。
- 示例:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class GlobalConfigService {
private config: any;
constructor() {
// 初始化配置
this.config = { apiUrl: 'https://example.com/api' };
}
getConfig() {
return this.config;
}
}
- **依赖注入工厂函数**:
- **策略**:当服务的创建需要复杂逻辑或者依赖于其他服务时,可以使用依赖注入工厂函数。这样可以在创建服务实例时,根据具体需求进行定制化创建,同时也可以控制服务的创建时机,提高性能。
- **示例**:
import { Injectable, Inject, InjectionToken } from '@angular/core';
export const API_URL = new InjectionToken<string>('API_URL');
export function httpServiceFactory(apiUrl: string) {
return new HttpService(apiUrl);
}
@Injectable()
export class HttpService {
constructor(private apiUrl: string) {}
get(url: string) {
// 实际的网络请求逻辑
return fetch(this.apiUrl + url);
}
}
@NgModule({
providers: [
{
provide: HttpService,
useFactory: httpServiceFactory,
deps: [API_URL]
},
{ provide: API_URL, useValue: 'https://example.com/api' }
]
})
export class AppModule {}
- 这里通过工厂函数 `httpServiceFactory` 创建 `HttpService`,并且可以灵活配置 `API_URL`。