ArangoDB FOXX插入Sheet文档时如何添加边并避免重复代码?
嘿,复制粘贴代码确实是个头疼的问题——不仅维护起来费劲,哪天改了一边忘了改另一边,还容易出bug!我给你几个靠谱的优化方案,你可以根据项目的架构复杂度来选:
方案1:提取公共工具函数
最直接的方式就是把创建ProjectToSheets边的逻辑抽成一个独立的公共函数,让需要用到它的地方直接调用就行。
比如咱们新建一个专门处理边逻辑的文件,比如projectSheetEdgeUtils.js:
// projectSheetEdgeUtils.js const ProjectToSheets = require('./path/to/ProjectToSheets'); async function createProjectToSheetEdge(fromProjectId, toSheetId, edgeData = {}) { try { return await ProjectToSheets.save(fromProjectId, toSheetId, edgeData); } catch (error) { // 统一处理错误,比如日志记录、抛出标准化错误 console.error('创建Project-Sheet边失败:', error); throw new Error('关联项目与表格失败'); } } module.exports = { createProjectToSheetEdge };
然后在Sheet的POST路由里直接调用这个函数,不用再复制粘贴:
// Sheet的POST路由 const { createProjectToSheetEdge } = require('./projectSheetEdgeUtils'); router.post(async function (req, res) { const sheet = req.body; // 这里假设req里能拿到关联的projectId,比如从参数、body或者用户上下文里取 const projectId = req.body.projectId; // 按需调整获取方式 try { const sheetMeta = await Sheets.save(sheet); // 直接调用公共函数创建边 const edgeMeta = await createProjectToSheetEdge(projectId, sheetMeta._id); res.status(201).json({ sheet: sheetMeta, edge: edgeMeta }); } catch (error) { res.status(500).json({ message: error.message }); } });
原来的ProjectToSheets路由也可以换成调用这个公共函数,彻底消除重复代码。
方案2:封装业务服务层
如果项目规模稍大,更推荐把业务逻辑封装到专门的服务层里,路由只负责处理HTTP请求和响应,具体业务逻辑都交给服务层。
比如创建一个SheetService.js:
// SheetService.js const Sheets = require('./path/to/Sheets'); const { createProjectToSheetEdge } = require('./projectSheetEdgeUtils'); class SheetService { async createSheetAndLinkToProject(sheetData, projectId) { // 先保存Sheet const sheetMeta = await Sheets.save(sheetData); // 再创建关联边 const edgeMeta = await createProjectToSheetEdge(projectId, sheetMeta._id); return { sheet: sheetMeta, edge: edgeMeta }; } } module.exports = new SheetService();
然后路由里就变得非常简洁:
// Sheet的POST路由 const sheetService = require('./SheetService'); router.post(async function (req, res) { const { sheet, projectId } = req.body; // 按需调整参数 try { const result = await sheetService.createSheetAndLinkToProject(sheet, projectId); res.status(201).json(result); } catch (error) { res.status(500).json({ message: error.message }); } });
这种方式把业务逻辑和HTTP层解耦,不仅避免了重复代码,后续修改业务逻辑也不用动路由,维护起来更舒服。
方案3:事件驱动模式(适合复杂架构)
如果你的项目需要更高的解耦度,可以用事件驱动的方式:当Sheet创建成功后,触发一个sheet.created事件,然后专门的监听器来处理创建关联边的逻辑。
比如用Node.js的EventEmitter:
// eventEmitter.js const EventEmitter = require('events'); const eventEmitter = new EventEmitter(); module.exports = eventEmitter;
然后在Sheet保存的地方触发事件:
// Sheet的POST路由(或者服务层里) const eventEmitter = require('./eventEmitter'); router.post(async function (req, res) { const sheet = req.body; const projectId = req.body.projectId; try { const sheetMeta = await Sheets.save(sheet); // 触发Sheet创建成功的事件,带上需要的参数 eventEmitter.emit('sheet.created', { sheetId: sheetMeta._id, projectId }); res.status(201).json(sheetMeta); } catch (error) { res.status(500).json({ message: error.message }); } });
然后在专门的事件监听器文件里处理边的创建:
// eventListeners.js const eventEmitter = require('./eventEmitter'); const { createProjectToSheetEdge } = require('./projectSheetEdgeUtils'); // 监听sheet.created事件 eventEmitter.on('sheet.created', async ({ sheetId, projectId }) => { try { await createProjectToSheetEdge(projectId, sheetId); console.log('自动创建Project-Sheet边成功'); } catch (error) { console.error('自动创建Project-Sheet边失败:', error); // 这里可以加重试逻辑或者告警 } });
这种方式的好处是,Sheet的创建逻辑和边的关联逻辑完全分离,后续如果要加其他操作(比如发送通知、更新统计数据),只需要加新的监听器就行,不用修改原有代码。
内容的提问来源于stack exchange,提问作者Sven Bardos
相关产品推荐
相关产品推荐

