抽象化によるブランチ
2014年1月7日
「抽象化によるブランチ」とは、ソフトウェアシステムの大規模な変更を段階的に行うための手法[1]であり、変更が進行中でもシステムを定期的にリリースすることを可能にします。
ソフトウェアシステムの様々な部分が、置き換えたいモジュール、ライブラリ、またはフレームワークに依存している状況から始めます。
クライアントコードの一部と現在の供給者との間の相互作用を捉える抽象化レイヤーを作成します。クライアントコードのその部分を、この抽象化レイヤーを介して完全に供給者を呼び出すように変更します。
すべてのクライアントコードが抽象化レイヤーを使用するように徐々に移行し、供給者とのすべての相互作用が抽象化レイヤーによって行われるようにします。これを行う際に、この抽象化レイヤーを通じて供給者の単体テストカバレッジを向上させる機会を得ます。
同じ抽象化レイヤー[2]を使用して、クライアントコードの一部で必要な機能を実装する新しい供給者を構築します。準備ができたら、クライアントコードのその部分を新しい供給者を使用するように切り替えます。
すべてのクライアントコードが新しい供給者を使用するまで、欠陥のある供給者を徐々に置き換えます。欠陥のある供給者が必要なくなったら、削除できます。移行に不要になったら、抽象化レイヤーも削除することを選択できます。
上記の記述は一般的なケースですが、多くのバリエーションが発生する可能性があります。クライアントの一部だけを供給者と交換できない場合があり、すべてを一度に行う必要があります。供給者の機能を異なるサブコンポーネントに分割し、この手順全体をサブコンポーネントごとに実行できる場合があります。
これらのバリエーションにもかかわらず、共通のテーマがあります。抽象化レイヤーを使用して、複数の実装がソフトウェアシステムに共存できるようにします。1つの抽象化と複数の実装という概念を使用して、ある実装から別の実装への移行を実行します。システムが常に正しくビルドおよび実行されるようにし、置換を行っている間も継続的デリバリーを使用し続けられるようにします。可能な限り多くの方法で変更を段階的に行うようにします。
参考資料
Jez Humble氏は、Thoughtworksの継続的デリバリーツール「Go」のオブジェクトリレーショナルマッピングフレームワーク(ibatisからhibernate)とWeb UIフレームワーク(velocity/JsTemplateからRuby on Rails)の両方を置き換えるために、彼のチームが抽象化によるブランチをどのように使用したかを説明しています。
Paul Hammant氏は、抽象化によるブランチの使用に関する詳細、特にバージョン管理ブランチの代替としての使用について説明しています。
Steve Smith氏は、2つの実装がリクエストに対して同じ結果を返すことを検証するバリエーションについて説明しています。