レガシーASP.NET Webアプリをクリーンアーキテクチャで刷新した話 — 不具合率ほぼ0、カバレッジ80%達成まで
はじめに
2年かけて作ったシステムを捨てる英断から始まった。
外部委託中心の開発体制で作られたそのシステムは、クラスの責務が不明・可読性ゼロ・単体テスト不可能な状態だった。運用担当者として不具合調査をしても、ログを見ても何もわからない。コードをどこから追えばいいかすらわからない状態。
この記事は、2018年頃の実践記録です。現在はより優れたアーキテクチャや手法が存在していますが、当時の判断と試行錯誤のプロセスとして読んでいただければ幸いです。
導入前の課題
- クラスが責務で分かれておらず、どこに何の処理があるか不明
- 複数プロジェクト構成だが、プロジェクトごとの役割も不明確
- 単体テストを書ける構成でなく、品質の良し悪しが判断できない
- 不具合調査時にコードを追う起点すら見つからない
- 複数人開発でコードの実装方針がバラバラになっていた
一言で言うと「コードがどこで何をしているかわからない」状態。
アーキテクチャ選定プロセス
調査のきっかけ
当時は他システムでMVCを採用していたが、「役割ごとにどう構成すべきか」を改めて調査することにした。その中でMVC以外のアーキテクチャの存在を知り、幅広く調べ始めた。
DDDとの出会い
調査の中でDDD(ドメイン駆動設計)に出会い、書籍を読んで概念を理解した。さらに調べを進める中で、ジャストシステム社がJJUG CCC 2018 Springで発表した資料「DDDとクリーンアーキテクチャでサーバーアプリケーションを作っている話」に出会い、クリーンアーキテクチャの実践イメージが一気に具体化した。
クリーンアーキテクチャを選んだ決め手
- 単体テストのしやすさ — 依存関係のルールにより、ビジネスロジックを外部依存なしでテストできる
- 階層ごとの明確な役割分担 — どのクラスに何を書くかが明確になる
- プロジェクト単位でのリリース可能性 — 将来的な分割デプロイにも対応できる
導入前の検証
いきなり本番システムに適用せず、まず小さいテスト案件を作って約2ヶ月間「壊しては作り」を繰り返した。この期間で設計の勘所をつかんでから、本番への適用を判断した。
チームへの展開と反発の乗り越え方
展開方法
- まず自分で1機能をクリーンアーキテクチャで移行し、チームにデモ
- 以下をルールとして宣言:
- 単体テストの実装を必須とする
- カバレッジ75%未満はCIを通過させない
反発への対応
「単体テストを書くと実装時間が増える」「リリースが遅くなる」という懸念が出た。
これに対して、こう返した。
「カバレッジが高いということは、自分たちが実装したコードの品質が高いと、自分たちで証明できることになる。それに代わるものを示せるなら、別の方法でもいい。」
この一言でチームの納得を得て、導入に至った。
導入結果
| 指標 | 導入前 | 導入後 |
|---|---|---|
| テストカバレッジ | 計測不可 | 80%(全機能移行完了時点) |
| リリース後不具合率 | 高頻度 | ほぼ0 |
| 不具合調査時間 | 長時間(起点すら不明) | 大幅短縮 |
| 複数人開発の一貫性 | バラバラ | 金太郎飴のように統一 |
カバレッジは当初目標の75%から、最終的に全機能で80%まで達成。
チームの変化として特筆すべきは、「単体テストを書くことが苦じゃなくなった」メンバーが自然に増えていったこと。強制から文化へ変わった瞬間だった。
注意点:クリーンアーキテクチャが向かないケース
クリーンアーキテクチャは銀の弾丸ではない。副作用としてコード量が増える。
向いているケース:
- 大規模・長期保守が前提のシステム
- 複数人での並行開発が続くシステム
- リリース後の品質保証が重要なシステム
向いていないケース:
- 使い捨て・短期プロトタイプ
- 小規模で単一担当者が管理するシステム
- 頻繁に作り直しが発生するシステム
リリース後のメンテナンスコストを考えると、今回のシステムにはこのコストを支払う価値があった。ただし、すべてのシステムに適用すべきではない。
まとめ
モダナイゼーションを考える場合に、まず必要なのはプロジェクトの構造化であり、それを主導できる知識を持つ人間が設計を担うことが必須条件だと感じた。
今回の経験で一番の学びは、アーキテクチャ刷新は「技術の話」ではなく「チームの文化を変える話」だったということ。
「品質が高いと自分たちで証明できる」という一言がチームを動かした。
付記:2018年当時の選択として
この取り組みは2018年頃のものです。現在はVertical Slice ArchitectureやMinimal APIなど、より新しいアーキテクチャパターンや設計手法が登場しており、クリーンアーキテクチャが唯一の正解ではなくなっています。
当時の自分にとっては「単体テストを書ける構成にする」「複数人でも一貫した実装ができる」という課題を解決する最善の選択でした。技術は進化しますが、「なぜそのアーキテクチャを選ぶのか」という判断軸を持つことの重要性は変わらないと感じています。
技術スタック
- 言語:C#
- フレームワーク:ASP.NET
- アーキテクチャ:クリーンアーキテクチャ
- テスト:単体テスト(カバレッジ計測・CI自動実行)