第 2 章:搭起骨架——任务模型与程序边界

从 Task 数据模型开始,把命令解析、业务动作和文件存储拆成可以独立理解与测试的边界。

已发布文章工程实践入门4 分钟阅读发布于 2026年9月4日更新于 2026年9月4日
文章目录
  1. 从一条任务开始建模
  2. 理解程序的三个边界
  3. 让时间也成为依赖
  4. 设计统一入口
  5. 本章验收
项目路线Go 本地待办清单 CLI2 / 5
  1. 00项目总览
  2. 01第 1 章:先定义完成——需求、边界与验收标准准备
  3. 02第 2 章:搭起骨架——任务模型与程序边界实现
  4. 03第 3 章:让数据留下来——JSON 存储与安全替换实现
  5. 04第 4 章:完成核心功能——添加、查看、完成与删除实现
  6. 05第 5 章:把项目交付出去——测试、构建与复盘验证
LOCAL NOTE高亮并记笔记
0 / 1000 · 只保存在这台设备
READER NOTES第 2 章:搭起骨架——任务模型与程序边界》的本机笔记

从一条任务开始建模

任务需要稳定编号、标题、完成状态和创建时间。对应的 Go 结构体很直接:

type Task struct {
    ID        int       `json:"id"`
    Title     string    `json:"title"`
    Done      bool      `json:"done"`
    CreatedAt time.Time `json:"created_at"`
}

字段不是越多越好。只有当前需求会读取或修改的数据才进入模型。创建时间暂时不展示,但它是后续排序和迁移的重要事实,因此在创建时就保存。

理解程序的三个边界

CLI 程序边界

程序被拆成三层,但它们不是传统意义上的大型分层架构:

  • main 读取环境变量和命令行参数,组装程序。
  • App 理解 addlistdonedelete 的业务含义。
  • Store 只负责把 []Task 从文件读出或写回。

这样拆分后,测试可以直接调用 App.Run,传入一组参数和一个内存缓冲区,不必真的启动新的终端进程。

让时间也成为依赖

创建任务时需要当前时间。如果在业务代码中到处调用 time.Now(),测试结果会随运行时刻变化。把时间函数放到 App

type App struct {
    Store Store
    Now   func() time.Time
}

正式运行传入 time.Now,测试传入固定时间。这是依赖注入最朴素的形式:不需要框架,只需要把变化来源明确交给调用者。

设计统一入口

Run 先加载任务,再根据第一个参数分派命令:

func (app App) Run(arguments []string, output io.Writer) error {
    if len(arguments) == 0 {
        return errors.New("用法: todo add|list|done|delete")
    }
    tasks, err := app.Store.Load()
    if err != nil {
        return err
    }
    switch arguments[0] {
    case "add":
        return app.add(tasks, arguments[1:], output)
    case "list":
        return app.list(tasks, output)
    case "done":
        return app.setDone(tasks, arguments[1:], output)
    case "delete":
        return app.delete(tasks, arguments[1:], output)
    default:
        return fmt.Errorf("未知命令 %q", arguments[0])
    }
}

io.Writer 让输出目标可替换:正式程序传 os.Stdout,测试传 bytes.Buffer

本章验收

创建 go.modtask.goapp.gostore.gomain.go,确保 go test ./... 至少可以编译。此时命令还不必全部工作,但你应该能画出输入从 main 进入 App、再访问 Store 的方向。

JARVIS · 当前文章

有哪里没看懂?可以只问这篇。

Jarvis 会限定在《第 2 章:搭起骨架——任务模型与程序边界》及其公开关联内容中检索,并把引用定位回原文章节。

JARVIS / ARTICLE针对《第 2 章:搭起骨架——任务模型与程序边界》提问
当前范围第 2 章:搭起骨架——任务模型与程序边界不会悄悄扩大到全站
0 / 1000

准备好了。当前只会围绕第 2 章:搭起骨架——任务模型与程序边界回答。

RELATED BUILDS

关联项目

Go 本地待办清单 CLI

使用 Go 标准库完成一个支持添加、查看、完成和删除任务的命令行工具,并通过 JSON 文件持久化、自动化测试和跨平台构建形成完整交付闭环。

implementation积极维护

READER SIGNAL

这篇内容对你有帮助吗?

不需要登录。你的反馈会直接进入作者待处理列表。