結論から言うと、属性を持つオブジェクトは「その対象を説明するのに必要な情報だけ」をまとめると、扱いやすい設計になります。

クラスを使い始めると、属性をいくつ持たせるべきかで迷うことがあります。
必要な情報が少なすぎると使いづらくなりますし、何でも入れると役割がぼやけます。
この記事では、属性を持つオブジェクトを設計するときの基本を、動くコードと一緒に整理します。

この記事でわかること

  • 属性として持たせる値を決める考え方
  • 役割の違う情報を分ける理由
  • 実務で保守しやすいオブジェクト設計の基本

完成コード

完成コードは次の通りです。

class Task:
    def __init__(self, title, assignee, deadline, is_done=False):
        self.title = title
        self.assignee = assignee
        self.deadline = deadline
        self.is_done = is_done

    def mark_done(self):
        self.is_done = True

    def change_assignee(self, new_assignee):
        self.assignee = new_assignee

    def build_summary(self):
        status = "完了" if self.is_done else "対応中"
        return f"{self.title} | 担当: {self.assignee} | 締切: {self.deadline} | {status}"


task = Task("月次レポートを提出する", "佐々木", "2026-04-25")
print(task.build_summary())

task.change_assignee("高橋")
task.mark_done()
print(task.build_summary())

コードのポイント

このコードでは、タスクという対象を説明するために必要な属性だけを Task に持たせています。

  • title assignee deadline is_done は、タスクを扱うために必要な情報です
  • 担当者変更や完了状態の更新は、属性に対応するメソッドで行います
  • タスクと関係の薄い情報は、このクラスに入れていません

属性を選ぶときに「この対象を表すのに本当に必要か」を考えると、設計が整理しやすくなります。

コードを順番に説明します

主要な処理を分けて説明します。

1. まずは対象を説明するのに必要な情報を属性にします

class Task:
    def __init__(self, title, assignee, deadline, is_done=False):
        self.title = title
        self.assignee = assignee
        self.deadline = deadline
        self.is_done = is_done

タスクを扱うなら、何をするタスクか、誰が担当するか、いつまでか、といった情報が必要になります。
このように、その対象を説明するうえで基本になる情報を属性として持たせます。

逆に、そのクラスの役割と直接関係しない情報まで入れると、何のオブジェクトなのかが曖昧になります。
最初は「最低限何があればこの対象を扱えるか」を考えると整理しやすいです。

2. 更新される属性は、更新の意味が伝わるメソッドで扱います

    def mark_done(self):
        self.is_done = True

    def change_assignee(self, new_assignee):
        self.assignee = new_assignee

is_doneassignee は、作成後に変わる可能性がある属性です。
そのため、代入を外側に散らすより、意味がわかるメソッドを用意したほうが読みやすくなります。

task.change_assignee("高橋") のように書けると、何をしているのかが呼び出し側でもはっきりします。
属性を持つだけでなく、どう更新するかまで含めて考えることが設計では大切です。

3. 役割の違う情報は別のオブジェクトに分ける発想も必要です

    def build_summary(self):
        status = "完了" if self.is_done else "対応中"
        return f"{self.title} | 担当: {self.assignee} | 締切: {self.deadline} | {status}"

このメソッドは、タスクの属性を使って表示用の要約を作っています。
ここまでは Task と自然に結びついている処理です。

ただし、たとえば担当者のメールアドレス一覧、部署情報、通知設定まで Task に入れ始めると、役割が広がりすぎることがあります。
属性を設計するときは、関連はあるけれど別のまとまりとして扱うべき情報がないかも見ると、保守しやすい構成になります。

実務で使うときのポイント

実務では、属性を増やす前に「その値はこのオブジェクトの責務か」を確認すると、設計が崩れにくくなります。

  • 対象を説明するのに必要な情報だけを持たせると、クラスの役割が明確になります
  • 更新ルールがある属性は、専用メソッドとセットで考えると扱いやすいです
  • 関連する情報でも役割が違うなら、別クラスや別構造に分けたほうが保守しやすいです
  • 属性が増えすぎたら、1つのクラスが多くの責務を持ちすぎていないか見直すと効果的です

たとえば実務の管理ツールでは、タスク、担当者、通知設定、進捗履歴のように情報のまとまりが複数あります。
それぞれを無理に1つへ詰め込まず、対象ごとに属性を整理すると変更に強いコードになります。

よくある勘違い・注意点

  • 関連しそうな情報を全部属性に入れればよいわけではありません
  • 属性が多いほど便利とは限らず、責務が広がる原因になることがあります
  • 直接代入だけで更新し続けると、更新ルールが見えにくくなります
  • オブジェクト設計では、何を持つかだけでなく何を持たないかも重要です

まとめ

  • 属性を持つオブジェクトは、その対象を説明するのに必要な情報だけをまとめると扱いやすいです
  • 更新される属性は、意味が伝わるメソッドと一緒に設計すると読みやすくなります
  • 役割の違う情報は別のオブジェクトへ分ける発想が大切です
  • 実務では、責務が広がりすぎていないかを見ながら属性を設計します

次の記事