はじめに
今回Auth0連携を実装しているときに、「とりあえず動かす」ことを優先してDTOやリクエストクラスに値を直書きしてしまいました(トークンのような漏れたらまずい値ではありませんでした)
そのときは問題なかったのですが、後から要件が変わった瞬間に、呼び出し元のコードが壊れたり、修正箇所が大量に発生してしまいました。
この記事では、なぜそういう「壊れやすい設計」になってしまうのか、そして初心者のうちから意識しておきたい設計の考え方を整理してみます。
コードの細かい修正方法ではなく、「考え方」にフォーカスした内容です。
DTOやリクエストクラスに固定値を持たせると何が起きるか
DTO(Data Transfer Object)やリクエストクラスは、本来「データを運ぶ箱」のような役割です。
ここに以下のようなものを直接持たせてしまうと、後々つらくなります。
- 環境ごとに変わる値(ドメイン、クライアントIDなど)
- 今は1種類だけど、将来増えそうな区分値
- 特定のユースケースに依存した固定値
一見すると「ここに書いておけば楽」なのですが、その値が変わった瞬間に、
- DTOを使っているすべての処理を確認する必要が出る
- テストや他機能に影響が出やすくなる
という状態になります。
「ただの入れ物」のはずが、変更に弱いロジックの塊になってしまうのが問題でした。
引数がどんどん増える設計が破綻しやすい理由
もう一つよくあるのが、要件追加のたびに引数が増えていくパターンです。
最初はこんなイメージです。
- 必要な値は2つだけ
- メソッド呼び出しもシンプル
しかし要件が増えると、
- 「この値も必要になった」
- 「このフラグはこのケースだけ使う」
という形で引数が増えていきます。
結果として、
- 呼び出し側が「何を渡せばいいのか」分からなくなる
- 一部の引数だけが特定の条件で使われる
- 呼び出し元の修正範囲が広がる
という状態になりがちです。
これは、「この処理は何を責任としているのか」が曖昧なまま設計が進んでしまうことが原因だと感じました。
「変更に強いコード」とはどういうものか
今回の経験で、次の視点が重要だと気づきます。
- 値が変わっても、修正箇所が限定される
- 影響範囲が想像しやすい
- 「ここを変えればOK」が分かりやすい
つまり、変更が前提になっているコードが「変更に強いコード」だと思います。
Auth0連携のように、外部サービスに依存する処理は特に、
「将来変わるかもしれない」を前提に設計しておかないと、実務で困りそうだと感じました。
拡張性・保守性を意識した設計の考え方
ここからは、具体的な実装ではなく、考え方の整理です。
設定値は外に逃がす
- 環境ごとに変わる値
- 将来変更されそうな値
これらは、クラスの中に閉じ込めないほうが安全です。
「ここは設定」「ここはロジック」と分けて考えるだけでも、
変更時の心理的ハードルがかなり下がります。
クラスやメソッドの責務を小さく保つ
- DTOはデータを運ぶだけ
- 処理の判断は別の場所で行う
というように、「このクラスは何をするものか」をシンプルに保つと、
引数が増えすぎたり、修正が連鎖する事態を防ぎやすくなります。
依存関係を整理する
- あちこちから直接参照されている
- 変更すると広範囲に影響が出る
こういった状態は、設計が密結合になっているサインです。
「この処理はどこに依存しているのか?」を一段引いて考えるだけでも、
設計の見直しポイントが見えてきました。
まとめ
今回の経験から学んだのは、
- DTOやリクエストクラスに安易に固定値を持たせない
- 引数が増え続ける設計は、将来の破綻サイン
- 変更される前提で設計を考えることが大切
という点です。
今回の件で、ビルダーの書き方や、それに伴うnullチェックの重要性なども学べました。
今後もコーディング作業中に直面した問題について投稿しようと思います。
同じ初心者の方の助けになれば幸いです。