4日目のゴール
4日目のテーマも「1クラス1役割」。
ただし今日は、
「役割を“変化に強い形”にする」=保守性を意識したクラス設計
に一歩踏み込みます。
ここまでであなたはすでに、
- クラスは1人1仕事にする
- 誰が誰を知るか(依存の向き)を意識する
- クラス名と中身の役割をそろえる
という感覚をつかんでいます。
4日目は、
「じゃあ、どんな変化に耐えられるように設計しておくべきか」
を、ファイル保存アプリを題材に具体的に考えていきます。
保守性を「未来の変化」で考える
どんな変化が起きそうかを、先に想像してみる
保守性は、
「未来の変更にどれだけ耐えられるか」 です。
ファイル保存アプリで、ありそうな変化をいくつか挙げてみます。
- コンソールアプリから GUI アプリにしたくなる
- ファイル保存からデータベース保存に変えたくなる
- メモに「タグ」「優先度」「完了フラグ」など項目を増やしたくなる
- 保存形式をテキストから JSON に変えたくなる
- 保存先フォルダをユーザーごとに変えたくなる
4日目では、
「今のクラス設計で、これらの変化にどう耐えられるか」
を一つずつ見ていきます。
ここで効いてくるのが、
まさに「1クラス1役割」と「依存の向き」です。
ケース1:UI をコンソールから GUI に変えたい
どこが変わって、どこは変わらないべきか
理想はこうです。
- 変わるのは「UI担当のクラス」だけ
- Memo(データ)と MemoRepository(永続化)はそのまま
つまり、
「見せ方だけ変えたいのに、保存ロジックまで触りたくない」
という状態です。
今の構造を思い出しましょう。
- Memo … メモというデータの形だけ
- MemoRepository … メモの保存・読み込みだけ
- MemoApp … コンソールでの入出力とアプリの流れ
ここで、GUI に変えたくなったときにやりたいのは、
- MemoAppConsole(今のやつ)とは別に
MemoAppGui というクラスを作る - MemoRepository はそのまま使う
という形です。
重要なポイント
UI クラス(App)は MemoRepository に依存していていいが、
MemoRepository は UI を知らない。
この「依存の向き」が守られているからこそ、
UI だけ差し替える、ということができます。
ケース2:保存先をファイルからデータベースに変えたい
「保存方法だけ変えたい」という欲望
今は MemoRepository がテキストファイルに保存しています。
public class MemoRepository {
public void save(Memo memo) {
// ファイルに書く
}
public List<Memo> findAll() {
// ファイルから読む
}
}
Javaここで、こう思う未来が来るかもしれません。
「そろそろちゃんと DB に保存したいな…」
理想はこうです。
- App(UI)はそのまま
- Memo(データ)もそのまま
- MemoRepository の“中身”だけ差し替える
あるいは、
「ファイル版」と「DB版」を共存させる」 こともしたくなります。
ここで効いてくる「1クラス1役割」
MemoRepository の責務は
「Memo を永続化すること」だけであり、
「どこに、どうやって」は中に閉じ込められています。
App はこう書いているだけです。
MemoRepository repo = new MemoRepository(...);
repo.save(memo);
List<Memo> memos = repo.findAll();
JavaApp は
「ファイルか DB か」を知りません。
「MemoRepository がメモを保存してくれる人」
としか見ていません。
この状態になっていると、
将来こういうことができます。
MemoRepository repo = new FileMemoRepository(...);
// あるいは
MemoRepository repo = new DbMemoRepository(...);
Javaここから先はインターフェースの話になりますが、
4日目で感じてほしいのは、
「保存方法を変えたいとき、変わるのは“保存担当のクラス”だけであってほしい」
という設計の感覚です。
ケース3:メモの項目を増やしたい
「仕様変更」が一番よく起きるところ
例えば、こういう変更が来たとします。
- メモに「タグ」を付けたい
- 「重要フラグ(true/false)」を持たせたい
このとき、
どこを変えるのが自然かを考えます。
まず、メモという“意味の世界”が変わるので、
Memo クラスは確実に変わります。
public class Memo {
private final int id;
private final String date;
private final String body;
private final String tag; // 追加
private final boolean important; // 追加
}
Java次に、
保存形式も変わるので、
MemoRepository の formatLine と parseLine も変わります。
// 例: ID|日付|本文|タグ|重要フラグ
Javaここでの理想はこうです。
- 変わるのは Memo と MemoRepository だけ
- App(UI)は、ほぼそのまま
なぜか?
App は「Memo の中身の詳細」にはあまり踏み込まず、memo.getBody() や memo.getId() など、
必要な情報だけを使っているからです。
もし App のあちこちで
「行のフォーマット」や「タグの位置」などを意識していたら、
変更の波が UI にまで飛び火します。
これが、
「責務が混ざっていると、変更の波及範囲が広がる」
という典型例です。
ケース4:保存形式をテキストから JSON に変えたい
「中身の表現だけ変えたい」というパターン
今は 1行テキストで ID|日付|本文 という形式ですが、
将来こう思うかもしれません。
「JSON にしておいたほうが、他のツールからも扱いやすいな」
このとき、
変わるべきはどこか?
- Memo … 変わらない(意味は同じ)
- App … 変わらない(使い方は同じ)
- MemoRepository … 中身だけ変わる
つまり、
「永続化の表現方法」は MemoRepository の責務
として閉じ込めておくべき、ということです。
もし App の中に
「行を split して…」みたいなコードが散らばっていたら、
JSON への変更は地獄になります。
4日目でやるべき“実践的な見直し”
自分のクラスに「変化のシミュレーション」をかけてみる
今日の実践としておすすめなのは、
自分のファイル保存アプリに対して、
次の問いを一つずつ投げてみることです。
- UI をコンソールから GUI に変えたくなったら、どこを変える?
- 保存先をファイルから DB に変えたくなったら、どこを変える?
- メモの項目を増やしたくなったら、どこを変える?
- 保存形式を変えたくなったら、どこを変える?
そして、
「1箇所か、せいぜい2箇所だけ直せば済むか?」
をチェックしてみてください。
もし、
- どの変更でも 3〜4クラスをいじらないといけない
- 特に App の中身を毎回いじることになる
という状態なら、
責務の分離がまだ甘いサインです。
逆に、
- UI の変更 → UI クラスだけ
- 保存方法の変更 → Repository だけ
- データ構造の変更 → Memo と Repository
くらいで済むなら、
かなり“保守性の高い設計”になっています。
4日目で本当に掴んでほしい感覚
4日目のテーマは、
「1クラス1役割を、“未来の変化”という物差しで評価する」
ことでした。
まとめると、こうです。
- 保守性=未来の変更にどれだけ耐えられるか
- 変更シナリオを具体的に想像してみる
- 「この変更で、どのクラスだけが変わるべきか?」を考える
- それが実現できていれば、責務と分離はうまくいっている
- どの変更でも同じクラスをいじるなら、そのクラスは“なんでも屋”になっている
あなたはもう、
「クラスを分けられる人」から一歩進んで、
「クラスを“未来の変化”まで見据えて設計できる人」
の領域に入りかけています。
この感覚を持ったまま、
次は「インターフェース」や「抽象クラス」で
さらに設計の自由度と保守性を上げていくことができます。

