<audio id="audio" title="课前热身 | 这些需求给到你，你会怎么写代码？" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/9c/b2/9ca637986e4029b124e11be0af947eb2.mp3"></audio>

你好，我是郑晔。

我在开篇词中提到，缺乏识别代码坏味道的感觉，这才让很多问题代码堂而皇之地留在了自己的眼皮底下。识别坏味道，单纯学理论是不够的，你得结合具体问题进行分析，所以我才在课程中加入了大量真实的代码案例，帮助你理解坏味道。当然，除此之外，你还要有足够多的练习。

为了让你能够深度地参与到这个专栏的学习中，代码能力得到有效提升，我准备了一个课前热身的环节：大家一起来写代码。

我们要编写一个待办事项管理的软件，你可以看我下面给出的需求，它是以**命令行应用**的方式存在的。

## 第一阶段：基本功能

- 添加 Todo 项。

```
todo add &lt;item&gt;


1. &lt;item&gt;


Item &lt;itemIndex&gt; added

```

- 完成 Todo 项。

```
todo done &lt;itemIndex&gt;


Item &lt;itemIndex&gt; done.

```

- 查看 Todo 列表，缺省情况下，只列出未完成的 Todo 项。

```
todo list


1. &lt;item1&gt;
2. &lt;item2&gt;


Total: 2 items

```

- 使用 all 参数，查看所有的 Todo 项。

```
todo list --all


1. &lt;item1&gt;
2. &lt;item2&gt;
3. [Done] &lt;item3&gt;


Total: 3 items, 1 item done

```

要求：

1. Todo 项存储在本地文件中；
1. Todo 项索引逐一递增。

## 第二阶段：支持多用户

- 用户登录。

```
todo login -u user
Password: 


Login success!

```

- 用户退出。

```
todo logout


Logout success!

```

要求：

1. 只能看到当前用户的 Todo 列表；
1. 同一个用户的Todo 项索引逐一递增；
1. 当前用户信息存储在配置文件中 ~/.todo-config。

## 第三阶段：支持 Todo 列表导入和导出

- Todo 列表导出。

```
todo export &gt; todolist

```

- Todo 列表导入。

```
todo import -f todolist

```

## 第四阶段：支持数据库持久化

在配置文件中，配置数据库连接信息。

- 初始化数据库。

```
todo init

```

要求：

1. 没有数据库的情况下，使用本地文件；
1. 在有数据库的情况下，使用数据库；
1. 在本地文件已经存在的情况，将本地信息导入到数据库中。

以上我给出的是最基本的需求，你可以根据自己的实际编码情况，适当补充一些细节，比如，相应的错误提示。

你可以用自己最熟悉的程序设计语言、按照自己最习惯的方式编写代码，并在 Github 上以公开仓库的方式提交自己的代码，将仓库链接贴在这节课的留言区下，我会顺着链接找到你的仓库，去查看你写的代码。

为了方便代码的阅读，请你按如下要求编写你的代码：

- 在项目的 README 文件中，写出如何构建和执行你的应用；
- 需求分成四个阶段，请你按顺序依次完成每个阶段的需求；
- 每完成一个阶段的代码，创建一个 tag，tag 名称分别为 todo-phase-1、todo-phase-2、todo-phase-3、todo-phase-4。

之所以要把需求分阶段，主要是方便大家参与，即便你时间有限，只写第一个阶段的代码，依然是一个完整的需求。学过《[10x 程序员工作法](https://time.geekbang.org/column/intro/100022301)》的同学都知道，任务分解是一个重要的工作原则，分阶段需求其实就是一种需求层面上的任务分解。

在专栏结束之前，我会专门制作一期加餐，点评大家的代码；同时，我也会选出代码写的最整洁的3位同学，送出价值[149元的华为智能体脂电子称](https://shop18793264.m.youzan.com/wscgoods/detail/360fd7mtqj71k?banner_id=ag.18601096~goods.2~106~aKZdZHmE&amp;alg_id=0&amp;reft=1608863554063_1608863999769&amp;spm=f.69794282_ag.18601096)。

<img src="https://static001.geekbang.org/resource/image/5d/6b/5d6600a2769c6924d732d80eb365206b.jpg" alt=""><br>
欢迎加入这次编码的训练中，期待你在留言区分享你的代码。
