12日目のゴールとテーマ
12日目のテーマは 「クラス同士を組み合わせて“アプリの世界観”を作る」 です。
昨日は「Task という1つのクラス」を作りました。
今日はそこから一歩進んで、
- クラスを“複数”作る
- クラス同士が協力してアプリを動かす
- 「管理する側のクラス」を作ってアプリの構造を整理する
という、アプリ設計の本質に踏み込みます。
ここまで来ると、あなたはもう「文法を覚える段階」ではなく、
「アプリをどう設計するか」を考える段階に入っています。
クラスを増やすと何が嬉しいのか
「役割ごとにクラスを分けると、アプリが読みやすくなる」
昨日の Task クラスは、
「タスク1件分の情報と、そのタスクに関する処理」をまとめたものでした。
でも、アプリ全体を考えると、
「タスクをまとめて管理する役割」も必要になります。
例えば、
- タスクを追加する
- タスク一覧を返す
- タスクを削除する
- ファイルに保存する
- ファイルから読み込む
こういった“管理者”の役割は、Task クラスには向きません。
そこで登場するのが TaskManager クラス です。
Task は「1件分」
TaskManager は「全体を管理する人」
この分担ができると、アプリの構造が一気に整理されます。
TaskManager クラスの最小形を作る
「タスクリストを持つクラス」
まずは、最小限の TaskManager を作ってみます。
class TaskManager:
def __init__(self):
self.tasks = []
def add(self, task):
self.tasks.append(task)
def all(self):
return self.tasks
Pythonここでのポイントを丁寧に見ていきます。
__init__ の中で self.tasks = []
→ TaskManager は「タスクのリスト」を持つ存在。
add(self, task)
→ Task オブジェクトを受け取ってリストに追加する。
all(self)
→ タスク一覧を返す。
これだけでも、辞書やリストを直接扱うよりずっと読みやすくなります。
TaskManager に「削除」機能を足す
「番号を指定して削除する」
タスク管理アプリでは、削除もよく使います。
TaskManager に削除メソッドを追加してみましょう。
class TaskManager:
def __init__(self):
self.tasks = []
def add(self, task):
self.tasks.append(task)
def all(self):
return self.tasks
def delete(self, index):
if 0 <= index < len(self.tasks):
del self.tasks[index]
return True
else:
return False
Pythonここでの重要ポイントは、
- 削除できたら True
- 範囲外なら False
という「結果を返す」設計にしていることです。
こうしておくと、呼び出し側で
if manager.delete(2):
print("削除しました")
else:
print("その番号のタスクはありません")
Pythonのように分岐できます。
TaskManager に「保存・読み込み」を持たせる
「管理者がデータの出し入れを担当する」
TaskManager がタスク全体を管理するなら、
ファイル保存・読み込みも TaskManager の仕事にできます。
import datetime
class TaskManager:
def __init__(self):
self.tasks = []
def add(self, task):
self.tasks.append(task)
def all(self):
return self.tasks
def delete(self, index):
if 0 <= index < len(self.tasks):
del self.tasks[index]
return True
return False
def save(self, filename):
with open(filename, "w", encoding="utf-8") as file:
for task in self.tasks:
line = task.name + "," + task.deadline.isoformat() + "\n"
file.write(line)
def load(self, filename, task_class):
self.tasks = []
try:
with open(filename, "r", encoding="utf-8") as file:
for line in file:
line = line.strip()
if line == "":
continue
name, date_text = line.split(",")
year, month, day = map(int, date_text.split("-"))
deadline = datetime.date(year, month, day)
task = task_class(name, deadline)
self.tasks.append(task)
except FileNotFoundError:
self.tasks = []
Pythonここでの深掘りポイントは、
TaskManager が Task クラスを知らないようにしている
load の引数に task_class を渡しているのがポイントです。
manager.load("tasks.txt", Task)
Pythonと呼び出すことで、
- TaskManager は「タスクの作り方」を知らない
- Task クラスの変更に TaskManager が巻き込まれない
という“ゆるい結びつき”が実現します。
これはアプリ設計でとても大事な考え方です。
Task クラスと TaskManager クラスを組み合わせる
「役割分担」が見えてくる
ここまで来ると、アプリの構造はこうなります。
Task
→ 1件分の情報とロジックを持つ
TaskManager
→ 複数の Task をまとめて管理する
main(アプリ本体)
→ メニューを出し、TaskManager に仕事を依頼する
この3層構造は、現実のアプリでもよく使われる形です。
12日目のミニアプリ:クラス2つで作るタスク管理
「Task × TaskManager × メニュー」の三位一体
以下は全体のイメージです(コードは短縮版)。
import datetime
class Task:
def __init__(self, name, deadline):
self.name = name
self.deadline = deadline
def status_text(self):
today = datetime.date.today()
diff = (self.deadline - today).days
if diff > 0:
return f"あと {diff} 日"
elif diff == 0:
return "今日が締切!"
else:
return f"期限切れ({-diff} 日過ぎ)"
class TaskManager:
def __init__(self):
self.tasks = []
def add(self, task):
self.tasks.append(task)
def all(self):
return self.tasks
def delete(self, index):
if 0 <= index < len(self.tasks):
del self.tasks[index]
return True
return False
def main():
manager = TaskManager()
while True:
print("1: 追加 2: 一覧 3: 削除 0: 終了")
choice = input("番号を選んでください: ")
if choice == "1":
name = input("タスク名: ")
date_text = input("締切(YYYY-MM-DD): ")
y, m, d = map(int, date_text.split("-"))
task = Task(name, datetime.date(y, m, d))
manager.add(task)
elif choice == "2":
for i, task in enumerate(manager.all(), start=1):
print(i, task.name, "→", task.status_text())
elif choice == "3":
index = int(input("削除する番号: ")) - 1
if manager.delete(index):
print("削除しました")
else:
print("その番号はありません")
elif choice == "0":
break
main()
Pythonここでの重要ポイントは、
- main は「メニューと入力」だけ
- TaskManager は「タスク全体の管理」
- Task は「1件分のロジック」
という役割分担ができていることです。
クラスを増やすとアプリが“世界”になる
「登場人物が増えると、アプリが自然に読める」
クラスを使うと、コードが「物語」になります。
Task
→ タスクという“登場人物”
TaskManager
→ タスクを管理する“司令塔”
main
→ アプリ全体の“舞台監督”
こういう構造になると、
コードを読むときに「何がどこにあるか」が自然に分かるようになります。
これは、辞書やリストだけでは絶対に得られない感覚です。
12日目で一番大事な感覚
「クラスは“役割を持った登場人物”」
今日あなたに持ってほしい感覚はこれです。
クラスはただの文法ではなく、
アプリの中に「役割を持った登場人物」を作るための仕組みです。
Task は「タスクというキャラクター」
TaskManager は「タスクを管理するキャラクター」
こうやって登場人物を増やしていくと、
アプリの構造がどんどん自然になっていきます。
12日目のまとめ
今日のキーポイントを短く整理すると、
- クラスは「役割を持った登場人物」
- Task は「1件分の情報とロジック」
- TaskManager は「複数の Task を管理する存在」
- main は「アプリ全体の流れを決める場所」
- クラスを分けると、アプリの構造が読みやすくなる
もし余裕があれば、次の機能を TaskManager に足してみてください。
- 「締切が近いタスクだけを返す」
- 「名前で検索する」
- 「優先度で並び替える」
ここまで来ると、あなたはもう「クラスを使ってアプリを設計できる人」です。
13日目・14日目では、この力をさらに“アプリとして完成させる方向”に伸ばしていきます。
