面试题答案
一键面试基于职责单一性原则进行模块划分的方法
- 功能分离:将不同功能逻辑分离到独立模块。例如,用户认证功能与订单处理功能,应分别在不同模块实现,避免一个模块既处理认证又处理订单相关业务。
- 数据处理与业务逻辑分离:数据访问层模块负责与数据库交互,获取或存储数据;业务逻辑模块基于这些数据进行业务规则处理。如在电商系统中,商品数据的数据库查询在数据访问模块,而根据查询结果计算商品折扣等业务逻辑在业务逻辑模块。
- 关注点分离:把不同关注点的代码分到不同模块。比如日志记录、错误处理等功能各自形成模块,不与核心业务模块混合。日志模块专门负责记录系统运行中的各种信息,不干扰业务逻辑执行。
遵循该原则的模块具体实现示例
假设构建一个简单的用户管理微服务,以用户注册功能为例:
- 数据访问模块(userDataAccess.js)
const mysql = require('mysql');
// 创建数据库连接
const connection = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'password',
database: 'users_db'
});
connection.connect();
// 定义插入用户数据的函数
const insertUser = (userData, callback) => {
const sql = 'INSERT INTO users SET?';
connection.query(sql, userData, (error, results, fields) => {
if (error) {
callback(error, null);
} else {
callback(null, results);
}
});
};
module.exports = {
insertUser
};
- 业务逻辑模块(userRegistrationLogic.js)
const { insertUser } = require('./userDataAccess');
// 验证用户数据格式
const validateUserData = (userData) => {
if (!userData.username ||!userData.password) {
throw new Error('用户名和密码是必填项');
}
return true;
};
// 处理用户注册业务逻辑
const registerUser = async (userData) => {
try {
validateUserData(userData);
const result = await new Promise((resolve, reject) => {
insertUser(userData, (error, results) => {
if (error) {
reject(error);
} else {
resolve(results);
}
});
});
return result;
} catch (error) {
throw error;
}
};
module.exports = {
registerUser
};
- 路由模块(userRoutes.js)
const express = require('express');
const { registerUser } = require('./userRegistrationLogic');
const router = express.Router();
router.post('/register', async (req, res) => {
try {
const result = await registerUser(req.body);
res.status(201).send('用户注册成功');
} catch (error) {
res.status(400).send(error.message);
}
});
module.exports = router;
在上述示例中,数据访问模块仅负责与数据库交互插入用户数据;业务逻辑模块专注于验证用户数据及处理注册业务流程;路由模块只负责接收HTTP请求并调用业务逻辑模块处理,每个模块职责单一,符合职责单一性原则。