模块化规范
- 模块划分原则
- 单一职责原则:每个模块应只负责一项明确的功能。例如,将用户认证相关的逻辑集中在一个
authModule
中,包括登录、注册、验证等功能,避免不同功能混杂在同一模块。
- 高内聚低耦合:模块内部的代码紧密相关,模块之间的依赖尽量简单且少。如数据获取模块只专注于从 API 获取数据,不涉及过多业务逻辑处理,降低与其他模块的耦合度。
- 模块接口设计
- 明确输入输出:在模块文件顶部使用
export
关键字明确导出模块的接口。例如,对于一个工具函数模块 utils.ts
,导出的函数应定义清晰的参数类型和返回值类型:
// utils.ts
export function addNumbers(a: number, b: number): number {
return a + b;
}
- **使用接口或类型别名**:对于复杂的数据结构作为输入输出,使用接口或类型别名定义。比如在用户模块,定义用户数据结构接口:
// user.ts
export interface User {
id: number;
name: string;
email: string;
}
export function getUserById(id: number): User | null {
// 模拟数据获取逻辑
const users: User[] = [
{ id: 1, name: 'John', email: 'john@example.com' },
{ id: 2, name: 'Jane', email: 'jane@example.com' }
];
return users.find(user => user.id === id) || null;
}
利用类型系统预防问题
- 严格类型标注
- 变量和函数参数:对所有变量和函数参数进行类型标注。如在函数定义时,明确参数类型和返回值类型:
function greet(name: string): string {
return `Hello, ${name}!`;
}
- **对象属性**:在定义对象类型时,标注每个属性的类型。例如:
const person: { name: string; age: number } = {
name: 'Alice',
age: 30
};
- 使用类型推断与严格模式
- 类型推断:利用 TypeScript 的类型推断功能,让编译器自动推导类型。但对于复杂场景,仍需显式标注以提高代码可读性和可维护性。例如:
let num = 10; // 类型推断为 number
- **严格模式**:启用 `strict` 模式,在 `tsconfig.json` 中设置 `"strict": true`。此模式会开启一系列严格的类型检查,如 `strictNullChecks`(严格空值检查),防止空值或未定义值的意外使用。
项目架构设计
- 分层架构
- 表现层(Presentation Layer):负责处理用户界面相关逻辑,如 React 组件(如果使用 React 框架)。组件应只关心如何展示数据,通过 props 接收来自业务逻辑层的数据。
- 业务逻辑层(Business Logic Layer):处理应用的核心业务逻辑。它调用数据访问层获取数据,进行业务规则处理,然后返回处理结果给表现层。例如,订单处理模块在这一层处理订单创建、修改、删除等业务逻辑。
- 数据访问层(Data Access Layer):负责与数据源(如数据库、API)进行交互。它封装了数据获取和存储的细节,为业务逻辑层提供统一的数据访问接口。如使用 Axios 封装 API 请求函数。
- 目录结构规划
- 按功能划分目录:每个主要功能模块有自己独立的目录。例如,项目根目录下有
auth
、user
、product
等目录,每个目录内包含该功能相关的模块文件、测试文件等。
- 公共目录:创建
common
目录存放通用的工具函数、类型定义、样式等。如 common/utils
存放工具函数,common/types
存放全局共享的类型定义。
- 文档化
- 代码注释:对关键函数、类、模块添加注释,解释其功能、参数、返回值等。例如:
/**
* 计算两个数的和
* @param a 第一个数
* @param b 第二个数
* @returns 两数之和
*/
export function addNumbers(a: number, b: number): number {
return a + b;
}
- **项目文档**:编写项目整体架构文档,描述各层的职责、模块之间的依赖关系、技术选型等,方便后续开发人员快速上手。