for文も嫌い
作成日時:2025-12-08
更新日時:2025-12-08
ポエム。
「if文が嫌い」の続き。
for文が嫌い
大体の理由は前回書いた「if文が嫌い」と同様。
複雑な条件と過剰なネストを書いてはならない。
何故ならば可読性が下がるから。
また、ループの中でのDB(または外部リソース)アクセスは許容できない。
何故ならば、その処理を通るたびにDBへのアクセスが発生するから。
DBと通信する回数分、無駄なオーバーヘッドが発生する。
DB参照は、ループの前に必要なデータを全て取得する。
DB更新は、ループの中で更新用データを作成して、ループの外で一括更新をする。
(但し、業務要件だったり、メモリーが不足していて更新用データを保持できない、など納得できる理由がある場合はこの限りではない。)
for文の中身は、シンプルであれ。
switch文も嫌い
breakやdefaultの記述漏れによるバグを作りかねない。
これらが漏れれば、意図しない処理が実行されてしまう。
breakの記述漏れの場合、それが意図的なfallthroughなのかバグなのかの判断ができない。
また、switch文の書き方や挙動はプログラミング言語ごとに微妙に異なるため、
別言語に慣れた開発者がプロジェクトに参入した場合、その差異に気づかずにバグを作ってしまう可能性がある。
「if文が嫌い」に書いたように、Simple FactoryやStrategyパターンを利用してswitch文を消したい。
switch文は、使うならばシンプルかつ正確に使え。
switch式は好き。
言語にもよるが、意図しないfallthroughを防いだり、列挙型の網羅チェックをできたりするから。
Stream, LINQ, メソッドチェインも嫌い
いいよね、Stream, LINQ, メソッドチェイン。
可読性が上がるし、余計なfor文や変数などを書かなくていいから好き。
しかし、シンプルであることが前提である。
メソッドチェインが10個も20個も繋がったり、またはネストしている場合(filterの中で別のStreamを作ったりとか)は嫌い。
チェインを1つずつ追って行って、最終的に何が格納されるか/何をしているのかを調べなければならない。
StreamやLINQで書けば可読性が高まるはずなのに、なぜ逆に低下するのか。
複雑ならばStreamやLINQを使わずに、メソッドに切り出してほしい。
メソッド名で、その処理が何であるかを語れ。
そのメソッドの中でシンプルなif/for文で実装してほしい。
Stream, LINQは書き方次第で処理速度が遅くなるし、メモリも余計に使うこともある。
適切に記述できないならば、または複雑になるならば、StreamやLINQを使わない。
文句ばかり言いやがって!じゃあ何ならいいんだ!?
シンプルだったらなんでもいいよ。
別に全ての制御文を否定するつもりはない。
むしろあらゆる書き方を推奨/許容している。
言語側が良いと思ってその書き方を準備してくれているのだから、使うべきである。
ただし「小さくシンプルであるならば」という条件付きで。
この条件が守られていないならば、そのコードは書き直したほうがいいと思う。
「if文やfor文だけで全て書け」と言っているのではない。
switch, Stream, LINQを書くべきならば書く。
もちろん現場のコーディング規約は順守する。
個人的には、シンプルなif文とfor文を好んで使う。
何故ならば、これらの意味はほぼ全てのプログラミング言語において共通であるため。
つまり何らかのプログラミング言語を学んだものであれば、コードの意味を理解できる。
コードを読む際の認知負荷を下げられると考えている。
(参考: CUPID特性のI:Idiomatic、慣用的/直感的なコード)
開発メンバー全員が対象言語に熟達している場合は、その言語固有の記法を使う。
要件としてパフォーマンスが求められているならばこの限りではない。
※参考:Node.jsのHTTPヘッダー解析処理のmatchKnownFields関数(if文まみれ。決定木 + V8エンジン最適化などの概念)
node/lib/_http_incoming.js at main · nodejs/node · GitHub
まとめ
シンプルに、分かるように書け。
PIE原則を順守せよ。
参考
参考キーワード:CUPID特性
参考キーワード:PIE原則