Day 71 のゴールと全体像
第8章では、いよいよ「アプリを作りながら学ぶ」フェーズに入っていきます。 Day 71 は、その最初の一歩――タスク管理アプリの要件定義の日です。
今日はまだ「ガリガリ実装する日」ではなく、
- どんな機能を持ったアプリにするのか
- そのために、どんなデータ構造が必要になりそうか
- 画面(今回はコンソール)でどう操作できると気持ちいいか
を、ゆっくり言葉にしていく時間です。
扱うキーワードは次のとおりです。
- タスク追加
- タスク一覧
- タスク検索
- タスク編集
- タスク削除
- 完了管理
- 優先度
- 期限
これらを、ひとつひとつ「どういう動きがあると嬉しいか」をイメージしながら、 最終的に 「タスク管理アプリの基本設計」 まで持っていきます。
タスク管理アプリの全体イメージ
どんなアプリにしたいかをざっくり描く
まずは、アプリのざっくりしたイメージを言葉にしてみます。
- コンソールベースのタスク管理アプリ
- メニューから操作できる
- タスクを追加して、一覧で確認できる
- タスクを検索したり、編集・削除したりできる
- 「完了したかどうか」「優先度」「期限」を管理できる
たとえば、こんな画面をイメージしてみてください。
=== タスク管理アプリ ===
1: タスク追加
2: タスク一覧
3: タスク検索
4: タスク編集
5: タスク削除
6: 完了状態の切り替え
7: 優先度で並び替え
8: 期限が近いタスク表示
0: 終了
選択してください:
この「メニューの顔」が、アプリの性格を決めていきます。
タスクという「データの形」を決める
タスクに必要な項目を洗い出す
機能を考える前に、 まずは「タスクって、どんな情報を持っているべきか?」を整理します。
今回の要件から、タスクに必要そうな項目は次のとおりです。
- タスクID(識別子)
- タスク名(タイトル)
- 詳細(メモ・説明)
- 完了フラグ(完了したかどうか)
- 優先度(高・中・低など)
- 期限(締め切りの日付)
これを C# のクラスにすると、こんなイメージになります。
// タスクを表すクラス
class TaskItem
{
public int Id { get; set; } // 一意なID
public string Title { get; set; } // タスク名
public string Description { get; set; } // 詳細・メモ
public bool IsCompleted { get; set; } // 完了しているかどうか
public int Priority { get; set; } // 優先度(数値で管理:1=高, 2=中, 3=低 など)
public DateTime? DueDate { get; set; } // 期限(ない場合もあるので ? にしておく)
}
C#コメントを付けておくことで、 「このプロパティは何を意味しているのか」が読みやすくなります。
Day 71 の時点では、 「タスクの形をこうしておこう」というレベルで十分です。 実際のロジックは、Day 72 以降で育てていきます。
機能1:タスク追加
どんな動きにしたいか
タスク追加は、このアプリのいちばん基本的な機能です。
イメージとしては、
- タスク名を入力する
- 詳細(メモ)を入力する
- 優先度を選ぶ(1: 高, 2: 中, 3: 低)
- 期限を入力する(任意)
- タスク一覧に追加される
という流れです。
コードのイメージ
// タスク一覧を管理するリスト
List<TaskItem> tasks = new List<TaskItem>();
int nextId = 1; // IDを連番で振るためのカウンタ
void AddTask()
{
Console.Write("タスク名を入力してください: ");
string title = Console.ReadLine();
Console.Write("詳細(メモ)を入力してください: ");
string description = Console.ReadLine();
Console.Write("優先度を入力してください (1: 高, 2: 中, 3: 低): ");
int priority = int.Parse(Console.ReadLine());
Console.Write("期限を入力してください (yyyy-MM-dd、未入力ならスキップ): ");
string dueText = Console.ReadLine();
DateTime? dueDate = null;
if (!string.IsNullOrWhiteSpace(dueText))
{
// 期限が入力されている場合だけ DateTime に変換
dueDate = DateTime.Parse(dueText);
}
var task = new TaskItem
{
Id = nextId++,
Title = title,
Description = description,
Priority = priority,
DueDate = dueDate,
IsCompleted = false // 追加時点では未完了
};
tasks.Add(task);
Console.WriteLine("タスクを追加しました。");
}
C#ここでは、
nextIdでタスクIDを連番で振る- 期限は任意入力なので、空なら
nullにしておく - 追加時点では
IsCompleted = falseにしておく
という要件を、コードに落とし込んでいます。
機能2:タスク一覧
どんな表示が気持ちいいか
タスク一覧は、アプリの「顔」ともいえる機能です。
- ID
- 完了状態
- 優先度
- 期限
- タイトル
あたりを、コンパクトに表示できると気持ちいいですね。
コードのイメージ
void ShowTasks()
{
Console.WriteLine("=== タスク一覧 ===");
if (tasks.Count == 0)
{
Console.WriteLine("タスクが登録されていません。");
return;
}
foreach (var t in tasks)
{
string status = t.IsCompleted ? "[完了]" : "[未完了]";
string priorityText = t.Priority switch
{
1 => "高",
2 => "中",
3 => "低",
_ => "不明"
};
string dueText = t.DueDate.HasValue
? t.DueDate.Value.ToString("yyyy-MM-dd")
: "期限なし";
Console.WriteLine($"ID: {t.Id} {status} 優先度: {priorityText} 期限: {dueText} タイトル: {t.Title}");
}
}
C#ここでは、
- 完了状態を
[完了] / [未完了]で表示 - 優先度を数値から「高・中・低」に変換
- 期限がない場合は「期限なし」と表示
という、人間にとって読みやすい表示を意識しています。
機能3:タスク検索
どんな検索があると便利か
検索機能は、
- タイトルに含まれるキーワードで検索
- 完了状態で絞り込み
- 優先度で絞り込み
など、いろいろ考えられますが、 Day 71 の段階では、まず 「タイトルの部分一致検索」 を要件として決めておくとよいです。
コードのイメージ
void SearchTasks()
{
Console.Write("検索キーワードを入力してください(タイトルに対して検索します): ");
string keyword = Console.ReadLine();
var results = tasks.FindAll(t =>
!string.IsNullOrEmpty(t.Title) &&
t.Title.IndexOf(keyword, StringComparison.OrdinalIgnoreCase) >= 0);
Console.WriteLine("=== 検索結果 ===");
if (results.Count == 0)
{
Console.WriteLine("該当するタスクがありませんでした。");
return;
}
foreach (var t in results)
{
string status = t.IsCompleted ? "[完了]" : "[未完了]";
Console.WriteLine($"ID: {t.Id} {status} タイトル: {t.Title}");
}
}
C#ここでは、
- タイトルにキーワードが含まれているかどうかで検索
- 大文字・小文字を区別しない検索にしている
という要件を、コードに反映しています。
機能4:タスク編集
どんな編集ができると嬉しいか
タスク編集では、
- タイトル
- 詳細
- 優先度
- 期限
などを変更できるようにしたいところです。
編集の流れとしては、
- 編集したいタスクの ID を入力する
- 該当タスクを表示する
- 各項目について「変更するかどうか」を聞く
- 入力があれば更新する
という形が分かりやすいです。
コードのイメージ
void EditTask()
{
Console.Write("編集したいタスクのIDを入力してください: ");
int id = int.Parse(Console.ReadLine());
var task = tasks.Find(t => t.Id == id);
if (task == null)
{
Console.WriteLine("指定されたIDのタスクが見つかりませんでした。");
return;
}
Console.WriteLine($"現在のタイトル: {task.Title}");
Console.Write("新しいタイトル(変更しない場合は空のまま): ");
string newTitle = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(newTitle))
{
task.Title = newTitle;
}
Console.WriteLine($"現在の詳細: {task.Description}");
Console.Write("新しい詳細(変更しない場合は空のまま): ");
string newDesc = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(newDesc))
{
task.Description = newDesc;
}
Console.WriteLine($"現在の優先度: {task.Priority}");
Console.Write("新しい優先度 (1: 高, 2: 中, 3: 低、変更しない場合は空のまま): ");
string newPriorityText = Console.ReadLine();
if (!string.IsNullOrWhiteSpace(newPriorityText))
{
task.Priority = int.Parse(newPriorityText);
}
Console.WriteLine($"現在の期限: {(task.DueDate.HasValue ? task.DueDate.Value.ToString("yyyy-MM-dd") : "期限なし")}");
Console.Write("新しい期限 (yyyy-MM-dd、空なら期限なしに変更): ");
string newDueText = Console.ReadLine();
if (string.IsNullOrWhiteSpace(newDueText))
{
task.DueDate = null;
}
else
{
task.DueDate = DateTime.Parse(newDueText);
}
Console.WriteLine("タスクを更新しました。");
}
C#編集機能は少し長くなりますが、 「現在の値を表示してから、変更するかどうかを聞く」 という流れにすると、ユーザーにとって親切な設計になります。
機能5:タスク削除
シンプルだけど慎重さが必要な機能
削除はシンプルですが、 「本当に消していいかどうか」を確認したくなる機能でもあります。
コードのイメージ
void DeleteTask()
{
Console.Write("削除したいタスクのIDを入力してください: ");
int id = int.Parse(Console.ReadLine());
var task = tasks.Find(t => t.Id == id);
if (task == null)
{
Console.WriteLine("指定されたIDのタスクが見つかりませんでした。");
return;
}
Console.WriteLine($"削除対象: ID={task.Id}, タイトル={task.Title}");
Console.Write("本当に削除しますか? (y/n): ");
string confirm = Console.ReadLine();
if (confirm?.ToLower() == "y")
{
tasks.Remove(task);
Console.WriteLine("タスクを削除しました。");
}
else
{
Console.WriteLine("削除をキャンセルしました。");
}
}
C#ここでは、
- 削除前に対象タスクを表示
yの確認があった場合のみ削除
という、安全寄りの設計を要件として決めています。
機能6:完了管理
完了状態を切り替える
完了管理は、
- タスクを「完了」にする
- 間違えて完了にしたものを「未完了」に戻す
という、トグル(切り替え)型の操作が分かりやすいです。
コードのイメージ
void ToggleComplete()
{
Console.Write("完了状態を切り替えたいタスクのIDを入力してください: ");
int id = int.Parse(Console.ReadLine());
var task = tasks.Find(t => t.Id == id);
if (task == null)
{
Console.WriteLine("指定されたIDのタスクが見つかりませんでした。");
return;
}
task.IsCompleted = !task.IsCompleted; // true/false を反転
Console.WriteLine($"タスクの完了状態を変更しました。現在の状態: {(task.IsCompleted ? "完了" : "未完了")}");
}
C#このように、 「完了状態を反転させる」というシンプルな操作にしておくと、 ユーザーも直感的に扱いやすくなります。
機能7:優先度
優先度をどう扱うか
優先度は、
- タスク追加時に設定する
- 編集で変更できる
- 一覧表示で「優先度順に並べる」機能を追加する
という形で扱うと、アプリとしての“便利さ”がぐっと増します。
並び替えのイメージ
void ShowTasksByPriority()
{
Console.WriteLine("=== 優先度順タスク一覧 ===");
var ordered = tasks
.OrderBy(t => t.Priority) // 1(高) → 2(中) → 3(低)
.ThenBy(t => t.DueDate ?? DateTime.MaxValue); // 同じ優先度なら期限が早い順
foreach (var t in ordered)
{
string priorityText = t.Priority switch
{
1 => "高",
2 => "中",
3 => "低",
_ => "不明"
};
string dueText = t.DueDate.HasValue
? t.DueDate.Value.ToString("yyyy-MM-dd")
: "期限なし";
Console.WriteLine($"ID: {t.Id} 優先度: {priorityText} 期限: {dueText} タイトル: {t.Title}");
}
}
C#Day 71 の段階では、 「優先度は数値で管理して、表示時に文字に変換する」 という方針を決めておくだけでも十分です。
機能8:期限
期限をどう活かすか
期限は、
- タスク追加・編集で設定できる
- 一覧表示で見えるようにする
- 「期限が近いタスクだけ表示する」機能を作る
といった形で活用できます。
期限が近いタスク表示のイメージ
void ShowUpcomingTasks()
{
Console.Write("何日以内の期限のタスクを表示しますか?: ");
int days = int.Parse(Console.ReadLine());
DateTime now = DateTime.Now;
DateTime limit = now.AddDays(days);
var upcoming = tasks.FindAll(t =>
t.DueDate.HasValue &&
t.DueDate.Value >= now &&
t.DueDate.Value <= limit);
Console.WriteLine($"=== 期限が {days} 日以内のタスク ===");
if (upcoming.Count == 0)
{
Console.WriteLine("該当するタスクがありませんでした。");
return;
}
foreach (var t in upcoming)
{
Console.WriteLine($"ID: {t.Id} 期限: {t.DueDate.Value:yyyy-MM-dd} タイトル: {t.Title}");
}
}
C#Day 71 では、 「期限を DateTime? で持って、こういう使い方ができる」 というイメージを持っておくことが大切です。
Day 71 用ミニテンプレート:要件定義の骨組み
最後に、今日の内容を「要件定義の骨組み」としてまとめておきます。
タスクのデータ構造
class TaskItem
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public bool IsCompleted { get; set; }
public int Priority { get; set; } // 1: 高, 2: 中, 3: 低
public DateTime? DueDate { get; set; } // 期限(任意)
}
C#必要な機能一覧(コンソールメニュー想定)
- タスク追加
- タスク一覧
- タスク検索(タイトル部分一致)
- タスク編集
- タスク削除
- 完了状態の切り替え
- 優先度順の一覧表示
- 期限が近いタスクの表示
この「機能のリスト」と「タスクの形」が決まっていれば、 Day 72 以降で、実際の実装にスムーズに入っていけます。
Day 71 のまとめ
Day 71 では、
- タスク管理アプリの全体イメージを描き
- タスクという「データの形」をクラスとして定義し
- タスク追加・一覧・検索・編集・削除・完了管理・優先度・期限 それぞれの機能について「どう動くと気持ちいいか」を言葉にし
- それを簡単なコードイメージに落とし込んでいきました。
要件定義は、 「コードを書く前に、アプリの性格を決める時間」です。
ここでしっかりイメージを固めておくと、 次の日からの実装がぐっと楽になり、 迷いが少ない状態でコードを書いていけます。
ぜひ、
- 自分ならどんなメニュー構成にしたいか
- どんな表示があると嬉しいか
- どこまで機能を絞るとちょうどよさそうか
といったことを、少し自分なりに考え直してみながら、 Day 72 以降の「タスク管理アプリ制作」に進んでいっていただければうれしいです。

