最近、生成AIがコードを書くこと自体は珍しくなくなった。
私自身もプロトタイプを作るときにはAIを使うことがある。
しかし、AIが登場したからといってソフトウェア設計の本質が
完全に変わるわけではないと考えている。
むしろ、AIによって 何が自動化され、何が残るのか を整理すると、
設計の本質はむしろはっきり見えるようになるのではないか。
AI時代を前提にしたうえで、
私自身がどうソフトウェア設計を考えているかをまとめる。
単なる忘備録である笑
1. 生成AIが変えるもの
生成AIによって大きく変わるのは、主に次のような仕事である。
- 定型実装
- CRUDの組み立て
- APIや画面の接着
- ボイラープレート
こうしたコードは、既に決まった構造の中に部品をはめているだけで、
構造そのものを生んでいるわけではない。
そのため、この種の仕事はかなりの部分がAIに置き換わると考えている。
しかし、次のような判断は残る。
- 問題をどう定義するか
- どこでコンテキストを切るか
- データをどこが所有するか
- どこを翻訳し、どこを内部概念として閉じるか
これらはソフトウェア設計の中心的な仕事であり、
AIがあっても残り続ける部分である。
2. AIとリファクタリングの関係
AIが生成したコードは、最初から綺麗とは限らない。
責務が混ざっていたり、概念の境界が曖昧だったりする。
しかしそれは特に問題ではない。
ソフトウェアの構造は、最初から完成形として作るものではなく、
リファクタリングの過程で徐々に収束していくものだからである。
典型的な流れは次のようになる。
AI → プロトタイプ生成 → リファクタリング → 抽象化 → 構造収束
最初に生成されたコードを観察し、
- 不要なものを削る
- 責務を分ける
- 名前を整える
- データ構造を整理する
という作業を繰り返すことで、
- データ構造
- 責務分割
- API
が自然な形に落ち着いていく。
重要なのは、構造はリファクタリングの過程で見えてくる
という点である。
AIはここで、実装を高速に試すための装置として機能する。
設計を置き換えるというより、
設計探索の速度を上げる道具に近い。
3. 私にとって設計の本質は「抽象化」であって、設計手法ではない
私は、ソフトウェア設計の本質は抽象化だと考えている。
もっとはっきり言えば、設計の中心は
「現実世界の本質的な関係を見抜き、それを概念として切り出し、
過不足なくモデル化すること」
である。
ここが設計の中心であって、
DDDやClean ArchitectureやFunctional Programmingが中心ではない。
それらは、抽象化された構造を壊さずに実装するための
方法論にすぎない。
設計の本質は
何を同じものとして扱い、何を別のものとして扱うかを見抜くこと
にある。
4. 設計の目的
設計の目的は、美しい構造を作ることではない。
- 速く
- 正確に
- 小さいコストで
動くコードを実現することである。
そしてそれを壊れにくくし、
必要になったら変更できるようにすることである。
そのために重要なのは
削れるものを削り、削れないものを残すこと
である。
その点において「ドメインが複雑だからモデルも複雑になる」
という説明をよく聞く。
しかし私は、この説明のかなりの部分を信用していない。
多くの場合、複雑さの原因は
- 概念の切り出しが雑
- コンポーネント分割が不適切
- 責務境界が曖昧
である。
つまり
複雑だから分けられないのではない。
分けられていないから複雑に見えている。
5. 境界はコンテキストで決まる
設計の中心は境界である。
境界を決める最も強い基準は
コンテキストの違いである。
コンテキストとは
- 同じ語彙
- 同じ前提
- 同じ責務
が通用する範囲である。
この前提が変わる地点が、
コンポーネント境界になる。
私がコンポーネント境界を考えるときに重視するのは
- データ
- コンテキスト
- 物理境界
の三つである。
特にデータの所有者は重要である。
どこがそのデータの真実を持つのかが曖昧だと、
設計は必ず崩れる。
6. 設計図を細かく残すことには価値を感じない
私は詳細な設計図を先に作り込むやり方を採らない。
理由は単純で、
ほぼ確実に嘘になるからである。
実装して初めて見える事実が大量にあるからだ。
私にとって
コードこそが設計の実体
である。
設計は仮説である。
実装してみると
- 不自然な責務
- 境界越えの違和感
- データ流れの詰まり
が必ず見つかる。
だから設計は
実装とリファクタリングの中で収束する。
7. 実装者と設計者は分離すべきではない
設計者と実装者を分けると、
設計は崩れる。
理由は単純で、
理解していないものを壊さずに実装するのは無理だから
である。
そのため
私は、大人数を壊れにくく回す設計よりも
理解している人が責任を持って作る開発
を好む。
設計と実装が同じ思考の流れの中にあるほうが、
構造と現実の往復が速いからである。
React / Spring / Rails のようなフレームワークは便利だ。
しかし
Controller / Service / Repository
といった構造をそのまま設計だと思うのは誤りである。
それは抽象化ではなく、
単なる分割である。
8. 私の開発スタイル
私のやり方はシンプルである。
- まず全体構成を決める
- 境界とプロトコルを決める
- あとはコードで設計する
細部の設計は、実装しながら決める。
コードは単なる出力ではなく、
最も密度の高い設計媒体だからである。