及时做APP开发实战(三)-数据模型设计
及时做APP开发实战(三)-数据模型设计好的数据模型设计是应用成功的基石。本文以及时做应用为例详细讲解如何从番茄工作法需求出发设计出合理的数据模型。一、需求分析1.1 番茄工作法简介番茄工作法是一种时间管理方法核心流程如下┌─────────────────────────────────────┐ │ 选择一个待完成的任务 │ └──────────────┬──────────────────────┘ │ ┌──────────────▼──────────────────────┐ │ 设定25分钟倒计时一个番茄钟 │ └──────────────┬──────────────────────┘ │ ┌──────────────▼──────────────────────┐ │ 专注工作直到计时器响起 │ └──────────────┬──────────────────────┘ │ ┌──────────────▼──────────────────────┐ │ 短暂休息5分钟 │ └──────────────┬──────────────────────┘ │ 每4个番茄钟后 长休息15分钟【图1番茄工作法流程图】1.2 功能需求拆解基于番茄工作法及时做应用需要以下核心功能待办管理创建、编辑、删除待办任务标记任务完成状态查看待办列表番茄钟计时25分钟倒计时开始、暂停、重置休息提醒数据统计今日完成任务数今日专注时长历史记录查看二、数据模型设计2.1 实体识别从需求中识别出两个核心实体待办任务TodoItem用户要完成的事项番茄钟记录PomodoroRecord每次专注的记录2.2 TodoItem模型设计/** * 待办任务数据模型 */exportinterfaceTodoItem{/** 唯一标识使用时间戳生成 */id:number;/** 任务文本内容 */text:string;/** 完成状态 */completed:boolean;/** 创建时间戳 */createdAt:number;/** 番茄钟完成次数 */pomodoroCount:number;}字段设计理由字段类型说明idnumber使用时间戳作为唯一标识简单高效textstring任务描述限制200字符completedboolean完成状态用于筛选和统计createdAtnumber创建时间用于排序和历史查询pomodoroCountnumber番茄钟次数显示专注程度为什么不存储番茄钟记录列表避免数据冗余番茄钟记录独立存储通过todoId关联统计时再聚合查询2.3 PomodoroRecord模型设计/** * 番茄钟记录数据模型 */exportinterfacePomodoroRecord{/** 唯一标识 */id:number;/** 关联的待办任务ID */todoId:number;/** 单次专注时长分钟 */duration:number;/** 完成时间戳 */completedAt:number;}字段设计理由字段类型说明idnumber记录唯一标识todoIdnumber外键关联TodoItemdurationnumber实际专注时长支持自定义completedAtnumber完成时间用于统计和历史查询为什么记录duration而不是使用固定值用户可能调整番茄钟时长支持自定义专注时长统计数据更准确三、工厂函数设计3.1 为什么需要工厂函数直接使用对象字面量创建对象存在风险容易遗漏字段默认值不统一类型检查不严格工厂函数解决了这些问题/** * 创建新的待办任务 */exportfunctioncreateTodoItem(text:string):TodoItem{return{id:Date.now(),text:text,completed:false,createdAt:Date.now(),pomodoroCount:0};}/** * 创建新的番茄钟记录 */exportfunctioncreatePomodoroRecord(todoId:number,duration:number):PomodoroRecord{return{id:Date.now(),todoId:todoId,duration:duration,completedAt:Date.now()};}3.2 工厂函数的优势// 不推荐直接创建对象consttodo:TodoItem{id:Date.now(),text:学习ArkTS,completed:false,createdAt:Date.now(),pomodoroCount:0};// 推荐使用工厂函数consttodocreateTodoItem(学习ArkTS);优势对比代码简洁一行代码完成创建默认值统一所有字段自动填充类型安全TypeScript自动推断类型易于维护修改默认值只需改一处四、业务逻辑实现4.1 TodoViewModel设计exportclassTodoViewModel{privatetodoList:TodoItem[][];/** * 添加新待办 */asyncaddTodo(text:string):PromiseTodoItem{consttodocreateTodoItem(text);this.todoList.push(todo);awaitthis.preferencesHelper.addTodo(todo);returntodo;}/** * 切换完成状态 */asynctoggleTodoComplete(todoId:number):Promisevoid{consttodothis.todoList.find(itemitem.idtodoId);if(todo){todo.completed!todo.completed;awaitthis.updateTodo(todo);}}/** * 增加番茄钟计数 */asyncincrementPomodoroCount(todoId:number):Promisevoid{consttodothis.todoList.find(itemitem.idtodoId);if(todo){todo.pomodoroCount;awaitthis.updateTodo(todo);}}}4.2 PomodoroViewModel设计exportclassPomodoroViewModel{privaterecords:PomodoroRecord[][];// 番茄钟配置常量privatestaticreadonlyDEFAULT_DURATION25;privatestaticreadonlySHORT_BREAK5;privatestaticreadonlyLONG_BREAK15;/** * 完成一次番茄钟 */asynccompletePomodoro(todoId:number,duration:numberPomodoroViewModel.DEFAULT_DURATION):PromisePomodoroRecord{// 1. 创建记录constrecordcreatePomodoroRecord(todoId,duration);this.records.push(record);// 2. 持久化存储awaitthis.preferencesHelper.addPomodoroRecord(record);// 3. 更新待办的番茄钟计数awaitthis.todoViewModel.incrementPomodoroCount(todoId);returnrecord;}}五、统计功能实现5.1 今日统计/** * 获取今日番茄钟数量 */getTodayPomodoroCount():number{consttodayStartthis.getTodayStartTimestamp();returnthis.records.filter(recordrecord.completedAttodayStart).length;}/** * 获取今日专注总时长分钟 */getTodayTotalDuration():number{consttodayStartthis.getTodayStartTimestamp();returnthis.records.filter(recordrecord.completedAttodayStart).reduce((total,record)totalrecord.duration,0);}/** * 获取今日开始时间戳 */privategetTodayStartTimestamp():number{consttodaynewDate();today.setHours(0,0,0,0);returntoday.getTime();}5.2 待办统计/** * 获取未完成的待办数量 */getActiveTodoCount():number{returnthis.todoList.filter(item!item.completed).length;}/** * 获取已完成的待办数量 */getCompletedTodoCount():number{returnthis.todoList.filter(itemitem.completed).length;}六、数据关联查询6.1 查询待办的所有番茄钟记录/** * 获取指定待办的番茄钟记录 */asyncgetPomodoroRecordsByTodoId(todoId:number):PromisePomodoroRecord[]{constrecordsawaitthis.getPomodoroRecords();returnrecords.filter(recordrecord.todoIdtodoId);}6.2 使用示例// 查询某个待办的专注历史consttodoId1234567890;constrecordsawaitpreferencesHelper.getPomodoroRecordsByTodoId(todoId);// 计算总专注时长consttotalDurationrecords.reduce((sum,r)sumr.duration,0);console.log(总专注时长:${totalDuration}分钟);七、数据验证7.1 输入验证exportclassValidateUtil{/** * 验证待办文本是否有效 */staticisValidTodoText(text:string):boolean{returntext.trim().length0text.trim().length200;}/** * 清理待办文本 */staticsanitizeTodoText(text:string):string{returntext.trim().substring(0,200);}}7.2 使用验证asyncaddTodo(text:string):PromiseTodoItem|null{// 验证输入if(!ValidateUtil.isValidTodoText(text)){console.warn(Invalid todo text);returnnull;}// 清理输入constcleanTextValidateUtil.sanitizeTodoText(text);// 创建待办consttodocreateTodoItem(cleanText);// ...}八、最佳实践总结8.1 数据模型设计原则单一职责每个模型只描述一类实体字段最小化只存储必要字段避免冗余类型安全使用TypeScript类型注解语义清晰字段命名要见名知意8.2 关联关系处理使用外键通过ID关联不嵌套对象独立存储关联数据分开存储按需查询需要时再聚合查询8.3 工厂函数使用统一创建入口所有对象创建通过工厂函数默认值集中管理便于维护和修改类型自动推断减少类型错误8.4 统计功能设计时间范围过滤使用时间戳过滤聚合计算使用reduce等方法聚合缓存优化频繁计算的统计数据可缓存九、扩展性考虑当前设计为后续扩展预留了空间自定义时长duration字段支持自定义历史查询completedAt字段支持时间范围查询标签分类可在TodoItem中添加tags字段优先级可在TodoItem中添加priority字段提醒时间可在TodoItem中添加reminderAt字段这种设计遵循了开闭原则对扩展开放对修改封闭。

相关新闻

并发控制核心:同步屏障与锁的本质区别

并发控制核心:同步屏障与锁的本质区别

并发控制核心:同步屏障与锁的本质区别 在复杂的并发编程与多智能体(Multi-Agent)图谱架构中,我们经常面临资源冲突与时序混乱的挑战。为了解决这些问题,底层架构通常会引入并发控制手段。 在众多的控制手段中&#xff…

2026/7/14 22:31:13阅读更多 →
C盘空间不足?系统清理原理与安全优化全攻略

C盘空间不足?系统清理原理与安全优化全攻略

你有没有遇到过这样的场景:明明没装几个软件,C盘却莫名其妙飘红,系统开始卡顿,连保存个文件都弹空间不足警告。更让人头疼的是,你不敢随便删东西,生怕一不小心把系统搞崩了。这种时候,很多人会去…

2026/7/14 22:31:13阅读更多 →
架构设计中的无用之用:拆解 lambda state: state 与同步屏障

架构设计中的无用之用:拆解 lambda state: state 与同步屏障

架构设计中的无用之用:拆解 lambda state: state 与同步屏障 在多智能体(Multi-Agent)图谱架构中,有时我们会遇到一行看似毫无意义的基础代码:lambda state: state。 这行代码在业务逻辑上什么都不做,但在复…

2026/7/14 22:31:13阅读更多 →
2026实测10款降AI率平台红黑榜!优缺点全曝光,达标率对标顶级水准

2026实测10款降AI率平台红黑榜!优缺点全曝光,达标率对标顶级水准

2026 年,AI 写稿、AI 生成内容已经成了学生党、打工人和内容创作者的日常,但随之而来的「AI 率过高」问题也成了新的麻烦:论文查重 AI 率超标、职场报告被判定 AI 生成、自媒体内容过不了平台原创审核… 为了帮大家解决这个痛点,我…

2026/7/14 23:11:17阅读更多 →
Unity动画优化:DOTween的SetEase函数与缓动曲线实战指南

Unity动画优化:DOTween的SetEase函数与缓动曲线实战指南

1. 项目概述:为什么你的Unity动画总感觉“差点意思”?如果你在Unity里做过动画,肯定遇到过这种尴尬:一个UI弹窗“唰”地一下弹出来,又“唰”地一下收回去,或者一个角色从一个点直线移动到另一个点。功能是实…

2026/7/14 23:11:17阅读更多 →
Python实战:从零构建中文词频分析器——jieba分词、停用词过滤与结果可视化

Python实战:从零构建中文词频分析器——jieba分词、停用词过滤与结果可视化

1. 为什么需要中文词频分析器在日常工作中,我们经常需要从大量中文文本中提取关键信息。比如内容运营要分析用户评论的热点话题,数据分析师要总结市场调研报告的核心观点,学术研究者要梳理文献的研究方向。这时候,一个能自动统计词…

2026/7/14 23:11:17阅读更多 →
深入FusionFix架构:模块化设计在游戏Mod开发中的工程实践

深入FusionFix架构:模块化设计在游戏Mod开发中的工程实践

1. 项目概述:从玩家到开发者的视角转变如果你和我一样,是个从《GTA IV》原版时代一路玩过来的老玩家,那你一定对EFLC(Episodes from Liberty City)那令人又爱又恨的优化和兼容性问题记忆犹新。FusionFix的出现&#xf…

2026/7/14 23:11:17阅读更多 →
Simulink——数据字典与信号对象的实战配置

Simulink——数据字典与信号对象的实战配置

1. Simulink数据字典与信号对象的核心价值在复杂系统建模中,信号管理往往成为工程师的痛点。传统工作区变量分散存储的方式会导致三个典型问题:属性定义不统一、跨模型共享困难、版本控制混乱。数据字典(Data Dictionary)正是为解…

2026/7/14 23:11:17阅读更多 →
AI搜索时代GEO优化实战全解:中小企业门店、工程采购低成本获客指南 摘要 本文聚焦中小企业、线下门店、工程采购领域的GEO优化落地应用,结合十年一线实操经验,从行业现状、适用场景、核心价值、常见误区

AI搜索时代GEO优化实战全解:中小企业门店、工程采购低成本获客指南 摘要 本文聚焦中小企业、线下门店、工程采购领域的GEO优化落地应用,结合十年一线实操经验,从行业现状、适用场景、核心价值、常见误区

摘要 本文聚焦中小企业、线下门店、工程采购领域的GEO优化落地应用,结合十年一线实操经验,从行业现状、适用场景、核心价值、常见误区、未来趋势五大核心维度,完成对GEO优化体系的全方位拆解。文章客观剖析了当下GEO赛道流量红利与行业乱象并…

2026/7/14 23:06:17阅读更多 →
VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异

VSCode TypeScript 环境配置对比:全局安装 vs 项目本地安装的4个关键差异当你在VSCode中启动一个新的TypeScript项目时,第一个技术决策往往从安装方式开始。这个看似简单的选择——全局安装还是项目本地安装——实际上会深刻影响你的开发流程、团队协作和…

2026/7/14 4:56:14阅读更多 →
智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手

智慧树刷课插件:5分钟实现自动化学习的智能助手 【免费下载链接】zhihuishu 智慧树刷课插件,自动播放下一集、1.5倍速度、无声 项目地址: https://gitcode.com/gh_mirrors/zh/zhihuishu 智慧树刷课插件是一款专为智慧树在线教育平台设计的Chrome浏…

2026/7/14 2:55:05阅读更多 →
Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案

Steam创意工坊下载器WorkshopDL:跨平台游戏模组获取的终极解决方案 【免费下载链接】WorkshopDL WorkshopDL - The Best Steam Workshop Downloader 项目地址: https://gitcode.com/gh_mirrors/wo/WorkshopDL 你是否在GOG或Epic Games Store购买了心仪的游戏…

2026/7/14 6:17:41阅读更多 →
【Cursor数据库安全红线】:自动执行SQL前必须校验的6项权限策略,金融级项目已强制落地

【Cursor数据库安全红线】:自动执行SQL前必须校验的6项权限策略,金融级项目已强制落地

更多请点击: https://intelliparadigm.com 第一章:Cursor数据库安全红线概览 Cursor 作为一款基于 AI 的智能编程助手,其本地数据库(SQLite 存储)承载着用户代码片段、会话历史、自定义规则及敏感上下文信息。理解其安…

2026/7/14 0:03:18阅读更多 →
【Notion AI写作避坑白皮书】:基于127份真实用户失败案例,总结6大致命误用陷阱

【Notion AI写作避坑白皮书】:基于127份真实用户失败案例,总结6大致命误用陷阱

更多请点击: https://codechina.net 第一章:Notion AI写作辅助的底层能力边界认知 Notion AI 并非通用大语言模型的直接封装,而是基于 Llama 系列与自研微调模型构建的轻量化推理服务,其输入上下文窗口严格限制在 8192 token&…

2026/7/14 0:03:18阅读更多 →
AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

AI Agent数据越界行为如何被精准溯源?——基于GDPR/CCPA双合规的5层审计框架实战指南

更多请点击: https://kaifayun.com 第一章:AI Agent数据越界行为的合规性挑战与溯源必要性 AI Agent在自主执行任务过程中,可能因提示注入、上下文污染或权限配置缺陷,无意或有意访问、缓存、传输受保护数据(如PII、G…

2026/7/14 0:03:18阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/14 15:07:30阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/14 4:45:36阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/14 2:42:17阅读更多 →