問題の出発点は「良かれと思って選んだ設計」、なぜアンチパターンを定義するのか
セッションは、本書のさらに詳しい紹介へと移った。和田氏は本書について、ボーナス章を除きすべての章が共通の構成を持っていると紹介する。すなわち、目的/アンチパターン/アンチパターンの見つけ方/アンチパターンを用いてよい場合/解決策を基本とする構成だ(章によってはミニアンチパターンが加えられる)。この構成からも分かるように、本書のねらいは、アンチパターンを単なる「やってはいけないこと」として並べるのではなく、文脈の中で理解できる形にすることだ。
さらに和田氏は、アンチパターンをチーム内で共有可能な知識にするためには「名付け」が重要だと説明する。本書では、すべてのアンチパターンに名前が与えられており、その名前を使うことで、設計の問題点を簡潔に伝えられるようになっている。設計の是非を一から説明しなくても、「それは○○アンチパターンではないか」と言うだけで、問題の構造や注意点を共有できるのだ。「アンチパターンを名前付きで整理することは、個人の経験をチームで再利用可能な知識に変えるための手段」だと和田氏は強調する。
この考え方は、AIが前提となる現代の開発環境において、さらに意味を増している。和田氏は、パターンが人と人のコミュニケーションだけでなく、人とAIのコミュニケーションにおいても有効である点に触れた。大規模言語モデルは、これまでのソフトウェアエンジニアリングの歴史を学習しており、デザインパターンやアンチパターンもすでに知識として内包している。そのため、「ジェイウォークアンチパターンとは何か」「その解決策は何か」と問いかければ、十分に妥当な回答が返ってくる。たとえばCREATE TABLE文を提示し、「この設計にSQLアンチパターンは含まれているか」と尋ねることも可能なのだ。
こうした前提を踏まえたうえで、和田氏は第2章「ジェイウォーク」を例として取り上げた。ジェイウォークとは「信号無視」を意味する言葉であり、本書では「本来守るべき構造を横断してしまう設計」を象徴するアンチパターンとして定義されている。しかしここで重要なのは、なぜこのような設計が生まれるのかという点だ。
和田氏はまず、アンチパターンは悪意や怠慢から生まれるものではないと指摘する。多くの場合、問題の出発点は「良かれと思って選んだ設計」にある。目の前の要件を、できるだけ少ない変更で素早く満たそうとした結果、その場では合理的に見える判断が、後になって大きな問題を引き起こしてしまう。このように、「その場では合理的な判断」に見えるからこそ、同じ失敗がさまざまな現場で繰り返され、「あるある」として再生産されてきたというのだ。
その代表例として、和田氏はジェイウォークアンチパターンの実例を紹介した。あるバグ管理システムにおいて、元々は製品ごとに連絡窓口となるユーザーを1人登録する仕様だったところ、「複数のユーザーを登録できるようにしてほしい」という要望が後から追加された。UIやテーブル構造を大きく変えずに対応したいという制約の中で、「担当者のアカウントIDをカンマ区切りの文字列として1カラムに格納する」という設計が選ばれた。
この判断は、一見すると手軽で現実的に見えた。しかし実際には、さまざまな問題が連鎖的に生じた。特定のユーザーに紐づく製品を検索するには正規表現(文字列の部分一致検索)が必要となり、インデックスが機能しない。集約処理ではカンマの数を数えるという歪んだロジックが入り込むため、オフバイワンエラー(件数が1つずれる典型的なバグ)の温床となった。さらに、更新や削除が煩雑になり、データの妥当性を保証することは事実上不可能に。いずれも、目の前の要求に応えようとして下した「善意の設計判断」が招いた結果である。
和田氏は、「アンチパターンとはこのような善意の設計が裏目に出た結果の集合知」だと整理する。だからこそ、名前を与えて改修しない限り、別の現場で再び踏み抜かれてしまうのだ。
