BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース リビルドか,リファクタか

リビルドか,リファクタか

原文(投稿日:2015/11/12)へのリンク

Agile Testing Days 2015で,Wouter Lagerweij氏が,テスト駆動開発や自動テスト,継続的デリバリといったアジャイルプラクティス導入をチームに導入するためには,レガシシステムをリファクタするよりリビルド(rebuild/再構築)の方が有効であるとする講演を行った。この講演は,自身のブログ記事“Don’t Refactor.Rebuild. Kinda”の内容に基づいたものだ。

InfoQはLagerweij氏とのインタビューで,ソフトウェアのリビルドがリファクタリングよりもリスクが少ないとするならば,リファクタリングをそれほど困難にしているのは一体何なのか,ソフトウェアのリビルドは継続的デリバリにとってどのように好都合なのか,といったことを聞くとともに,ソフトウェアのリビルドとリファクタリングに関して,氏のアドバイスを求めることにした。

InfoQ: リファクタリングが難しい理由はどこにあるのでしょう?

Lagerweij: リファクタリングは,それを行うこと自体で言えば,非常に簡単なプラクティスのひとつです。同じことが,例えばユニットテストについても言えます。自分のコードのテストを自分自身で一貫して書く,あるいは自分のコードの設計上の問題をクリーンアップする,といった作業を小刻みに実行している限りでは,難しいことは何もありません。

ですが,時間が経過していくと,そういった作業を改めて行うのは難しくなってきます。多くの人が“技術的負債(technical debt)”を口にするのはこのためなのですが,ここで起きているのは,Ward Cunningham氏が定義した(“Ward Explains Debt Metaphor”参照)本当の意味での技術的負債ではありません。技術的負債とは,現状の設計に対する改善を意識的に遅延するような決定のことを言いますが,通常はそういったことではなく,単に管理上の問題で制御不能に陥っているのです。

こういった状況は,何もソフトウェア産業に限ったものではありません。例えば,医療産業に携わっているリーン(Lean)実践者に聞いてみてください。外科医が手術前に必ず手を洗うというプラクティスは,患者の合併症リスクを半減しますが,積極的な伝道行動や構造的なチェックリストなどでコンプライアンスを得ることは困難です。

そのような理由から,チームのリファクタリングが遅れて,不整合なコードベースや”レガシコードベース”が生まれることが多いのです。こうしたチームはほとんど決まって,リファクタリングの経験を持っていない(そうでなければ実行しているでしょう)ので,混乱したコードがいつになったら整理されるのかはまったく分かりません。

このようなチームが,自らの“負債”を何とかしなければならない,と気付いた時には,改善に必要なスキルを得ることがあまりに困難であるゆえに,システムを前にして立ち往生してしまうのです!システムの小さな変更が,さまざまな部分に予期しない結果となって現れる状況では,リファクタリングを積極的に学ぶようなエクスペリエンスは拡がりません。さらに既存の,しかも密結合されたシステムに,ユニットテストを追加する作業の難しさや不愉快さといったものは,開発者ならば誰でも知っていることです。

要するに私が言いたいのは,ユニットテストやリファクタに着手することが困難になるほど時間がたった後で,そのようなスキルを適用してみても,成功する見込みはほとんどないだろう,ということなのです。逆に言えば,それをマスタする前に諦めてしまえば,成功のチャンスはかえって大きくなることにもなるのです。

InfoQ: ソフトウェアをリビルドする方が,リファクタリングよりもリスクが少ないという意見ですが,その理由を説明して頂けますか?

Lagerweij: 本当のところは,レガシシステムへの対処方法を知っているメンバによるチームであるならば,リファクタリングの方が間違いなく適切な選択だと思います。リスクも少ないですし,オーバーヘッドもリライトより少なくて済みます。

しかし,こういったスキルは,残念ながらまだかなり希少なのです。この種の仕事を経験したメンバがチームにいなければ,何をするにしても,さらに時間が掛かります。開発チームに対してだけでなく,ビジネスの上でも,ますますフラストレーションを募らせることになるでしょう。

このようなトラブルに見舞われている組織は,枚挙に暇がありません。要するに彼らは,自分たちの技術的問題を解決するために必要な知識を持ち合わせていないのです。そのために,競争力を備える上で必要な,新しい機能を構築することができないのです。数人の経験者を見つけることさえ難しい現状では,“少な過ぎる,遅過ぎる(too little, too late)”ケースがほとんどです。

このような状況ならば,書き直した方がよっぽどよいと言えるでしょう。

InfoQ: ソフトウェアのリビルドによって継続的デリバリを実現するにはどうすればよいのか,例をあげて頂けますか?この組み合わせは,どのような点で優れているのでしょう?

Lagerweij: リライトのメリットのひとつは,最初からやり直せる,ということです。つまり,今回はうまくいく,という確信を持てるのです。もちろん,そうは行かない場合がほとんどですが。先程述べたように,テストやリファクタなどを実施する上で最善の方法は,それを継続的に行うことです。とは言っても,前回は成功しなかったことが,突然うまく行くようになるでしょうか?

講演でこの件を議論した時,私は,かつて一緒に作業していたチームと交わした取り決めについて話をしました。その時の私たちは,テスト駆動開発(さらに振る舞い駆動開発も)を採用して,クリーンなコードを維持できた上に,ユニットテストのカバレッジも100%をキープしていました。レガシシステムに足を引かれなかったからこそ,これだけのことが可能になったのです。

さらに私たちは,規制を緩めるという誘惑に決して負けないこと,初日から完全な継続的デプロイメントを実施すること,などを決めていました。開発者がgithubにコードをプッシュすると,自動ビルド,テスト,運用システムへのデプロイが毎回行われる仕組みです。これによって,品質の維持に私たちの意識を集中することが可能になりました。テストを後回しすることは許されません。テスト未完了のコードをプッシュすると,ビルドを台無しにして,チーム全体のひんしゅくを買うことになります。さらには,運用中のシステムそのものを本当に壊してしまうことにもなりかねませんから,テストを省略する(あるいはカバレッジ数を稼ぐために,何もチェックしないユニットテストを書く)ようなことはしたくないでしょう。自分自身のためです。当然ですね。

また,テストのカバレッジが2.1%から2.0%に低下しても誰も気に留めないのに,100%から99.9%に低下するとチーム全体がその理由を探し始めるという,単純な心理的な効果も存在します。

それでも,学習するためのプロセスは必要です。やり直しさえすれば,魔法のように何でもうまくいくというものではありません。成功するチャンスが大きくなったというだけなのです。

InfoQ: ソフトウェアをリファクタリングする代わりに,リビルドの実施を検討しているチームに対して,何かアドバイスはありますか?

Lagerweij: まず最初に,リリース前にすべてをリビルドしようとは思わないことです。新しいシステムと旧システムを統合する方法を考えて,可能な限り早く,新システムのユーザに価値を提供してください。ストレンジパターンブランチ・バイ・アブストラクションといった方法が,ここでは役に立ちます。これを怠ると,プロジェクトがある時点で突然キャンセルされたり,あるいは継続できたとしても,いつまでたっても終わらない,というようなことになりかねません。

ふたつめは,自分に嘘をつかないことです。継続的デプロイのような規律を要するプロセスを使うことは,プロジェクトに対する外部からの要求に加えて,さらに負担を上乗せするように思えるかも知れません。しかしその規律は,以前と同じ過ちを繰り返して,まったく新しいレガシシステムを作ってしまうような事態を回避するために必要なのです。継続的リファクタリングやコードテストを実行する方法,コントロールを確立するには何種類のテストが必要なのか,デプロイメントを自動化するには,管理やエラー処理を扱うには,といった,新たなスキルの習得が迫られます。運用までのパスが短く直接的である場合には,これらはすべて,互いに関連性を持っています。

3番目に,おそらく最も重要なのが,ユーザの関与です!書き直しを行う場合には,通常にも増して,‘以前のシステムと同じようにしよう’という誘惑が頭を過るでしょう。そうなると今度は,ユーザの関与に関心を持てなくなってしまいます。しかし私たちは,ユーザが,何を求めているかを知らなくてはなりません。もはや必要のないものが何であるのかも,知っておく必要があります。採用されている機能に対する80/20のルールはご存知だと思いますが, それをテストして,今日実際に価値のあるものを提供する上で利用することが必要です。コードレベルでのリファクタリングを行う必要はなくても,要件やビジネスプロセス,さらにはビジネスモデルといったものの再検討はやはり必要なのです。

他にもまだ,行うべき作業はたくさんあると思いますが,これらの原則を心におくことで,コードをクリーンに保ち,チームは学習し,ユーザは幸福になることができるでしょう。

この記事に星をつける

おすすめ度
スタイル

BT