1. 技術的負債を理解する
技術的負債とは何かを説明するには、Clean Architecture第1章で紹介された以下の図がよいと思う。
図1-3を見てほしい。本当に恐ろしいグラフだ。これは、コード1行あたりのコストの変化を示している。
グラフの傾向から、持続可能性が低いことがわかる。同時期に企業がいくら利益を上げていようが関係ない。この曲線は、ビジネスモデルから利益を奪い去り、完全に崩壊させることはないにしても、企業を大きく失速させるだろう。
こうした生産性の変化の原因は何だろうか? リリース8にリリース1の40倍ものコストがかかっているのはなぜだろうか?
私が関わったすべてのプロダクトが、例外なくこのグラフと同じ生産性の加速度的低下を受けた。
例外は、今の所1つもない。
私見だが、私はこの生産性の低下を引き起こすものを技術的負債と定義する。
2. 技術的負債の実体は何か
ここは多種多様なものが挙げられると思う。
ぱっと思いつくものを以下に挙げた。
- ドキュメント不足
- 仕様記述の不在
- 一貫しないコード設計
- (チーム、あるいは企業の求める)技術水準にないコード
- バージョンアップされないインタープリタ、ライブラリ
- テスト不足
- ・・・
これについてだけでいくらでも文章が書けるが、本記事では深く掘り下げない。
3. 技術的負債に対する従来の2つの対応方法
上述の生産性低下の結果、基本的にすべてのプロダクトはある次点で新規機能の追加が不可能になりバグすらときに修正不可能になる。
その結果、企業は次のどちらかの選択肢を迫られる。
A. 既存プロダクトの完全リプレース
既存のプロダクトと同等な機能に加えて必要な新規機能を満たす新しいプロダクトを作成し、既存のプロダクトを置き換える手法。
一見かなりバカバカしい選択だが、現実的にはよく取られる。
幸か不幸かまだIT業界の流れは早く、同じプロダクトを再開発する言い訳が以下のようにたくさんある。
- マイクロサービス化
- 新しい言語に変更
- クラウド化
- DDD化
機能追加・保守ができない本当の理由を直視せず、上のような言い訳をして同じ機能のプロダクトを何度も何度も繰り返し開発する企業は確かに存在する。
一方で、マイクロサービスのような考え方ではたくさんの前提条件を敷いた上で上記のような再開発を肯定的に捉える向きもある1。
この手法は基本的に大量の人員と膨大な時間を必要とするものの、最終的に既存のプロダクトが破棄できれば一旦技術的負債は目減りするので人と金を余らせている企業ではそれなりに有効な方法である。
B. 衛星プロダクト
新たに必要な機能のみを含むプロダクトを、既存のプロダクトの隣に作成してそれらをなんらかの方法で連携させる手法。
連携には以下のような技術が使われる。
- 手動でのデータ同期
- 定期バッチ
- DBレベルでの相互参照/書き換え
- API連携
この方法は一見必要な投資が少なく済むように見える。
またプロダクトを別にできるので言語・設計・動作環境などを別にでき、既存のプロダクトの技術的負債を引き継がず機能追加できるように思える。
しかし、実はデメリットが非常に大きい。
理由は連携にある。技術的負債を抱えているようなプロダクトがまともな衛星プロダクトを作れるほど真っ当なAPI設計2をしていることはほぼありえない。結果的に衛星プロダクトの稼働は出来の悪いAPIに依存するか、DBレベル・定期バッチによる連携を迫られる。
出来の悪いAPIによる連携、DBレベルでの連携、定期バッチによる同期はどれも密結合を避けられない。
結果的に殆どの場合2つのプロダクトは融合して2種類の言語・設計・環境で動く1つのプロダクトになる。
この方法は以下の点で既存プロダクトの完全リプレースよりひどい。
- 技術的負債の総和は一切減らない
- 1つのプロダクトに2種類の言語・設計・環境が入り交じることで技術的負債をさらに上積みしている3
今まで見たシステムの中のワースト1,2はどちらもこのパターンだった。
4. 我々は技術的負債とどう戦うべきなのか
わからない。
DDDによる設計やclean architectureによる設計は、それらの主張する正しい設計により冒頭の図1-3のような機能の追加コストの爆発を抑えられると標榜している。
しかし、それらを実践した(少なくとも実践したと主張している)プロダクトのどれもコスト爆発を避けられていなかったし、自分で実践した結果も同様だった。そのプロダクトでのDDD実践者や自分が未熟だったと仮定しても、技術的負債を作らず開発するのはかなり難しいと思える。
マイクロサービス志向のアーキテクチャはDDDやcleanとは別のアプローチで技術的負債に対処しようとしている。DDDやcleanは主に1つのアプリケーション内の設計の試みであるが、マイクロサービス志向は1つのアプリケーションの粒度を細かくして機能単位に分解することによりアプリケーション1つ1つをDisporsableにして、いつでもコードを捨てられるようにしている。しかし、こちらもまだ試行され始めてたかだか4,5年でありマイクロサービスとして作られたものがどう退役するのか、などの知見は十分に集まっていない。
現実的なコストで持続的に機能追加・サービス継続できる。そのようなプロダクトは果たして作れるのだろうか・・・。