CodeZine(コードジン)

特集ページ一覧

コードがレガシーになる原因のほとんどは、人間に関係している~『レガシーソフトウェア改善ガイド』より

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2016/11/19 07:00

 翔泳社が11月10日に刊行した『レガシーソフトウェア改善ガイド』では、メンテナンスに膨大なコストが必要となる負の遺産的なコードやソフトウェアを誇れる資産へと昇華する手法を解説。悩みが尽きないという方のために、本書でどんなことが学べるのか、各章ごとに紹介します。

※いずれも『レガシーソフトウェア改善ガイド』より抜粋(記事掲載に合わせ一部改変)。

この本について

 本書のスコープは欲張りなもので、放置されたレガシーコードベースを、あなたの組織に価値をもたらす保守が可能で十全に機能するソフトウェアへと変身させるのに必要なことを、すべて伝授しようというのです。もちろん、1冊の本で、すべてを完全に網羅しようとする試みは、達成できるわけがないのですが、私はレガシーソフトウェアの問題点に対して、さまざまな角度からアプローチすることで、それに挑んでいます。

 コードがレガシーに(というのは、大ざっぱに言って、保守が困難に)なるには、多くの理由がありますが、ほとんどの原因は、技術ではなく人間に関係しています。もし人々のコミュニケーションが十分でなければ、人が組織を離れるとき、コードについての情報が失われます。同様に、開発者、管理者、そして組織全体が、仕事の優先順位を正しく設定しなければ、「技術的負債」(technical debt)が蓄積して維持できないレベルに達し、開発のペースが、ほとんどゼロにまで低下しかねません。このため、本書は折に触れて(とくに、時の経過に従って情報が失われるという問題を論じるときは)組織に関する側面を取り上げます。問題を意識することが、それを解決するための、重要な第一歩となるのです。

 ただし、この本に技術的な内容がないというのでは、まったくありません。本書は、Jenkins、FindBugs、PMD、Kibana、Gradle、Vagrant、Ansible、Fabricなどといった、広範囲なテクノロジーとツールを扱います。数多くのリファクタリングパターンを詳細に取り上げ、モノリスからマイクロサービスにいたるさまざまなアーキテクチャにおける関連メソッドを論じ、コードをリライトするときにデータベースを扱う戦略も見ていきます。

第1部 はじめに

 もしあなたが、それなりに大きなレガシーコードベースのリエンジニアリング(再設計)を計画しているのなら、時間をかけて下調べを行い、正しい方法で着手していることを確認すべきだ。この本の第1部では、大量の下準備を行うが、それは、あとで十分に報われる作業だ。

 第1章では、「レガシー」とはどういう意味なのかを調べ、保守が困難なソフトウェアが、どのような原因で作られるかを探る。第2章では、ソフトウェアの現状を数量的に検査して、リファクタリングの構造とガイドを提供するように、検証(インスペクション)の基盤(インフラストラクチャ)を設定する。

 あなたのソフトウェアの品質を計るのに、どのツールを使うかは、あなたが決めることだ。その選択は、実装に使う言語や、あなたが使った経験のあるツールなどに依存するだろう。第2章で使うのは、Javaで人気のあるソフトウェア品質検証ツール、FindBugs、PMD、Checkstyleだ。また、継続的インテグレーション(CI)サーバーとしてJenkinsをセットアップする方法も示す。このJenkinsについては、本書の随所で触れることになる。

第1章 レガシープロジェクトの難題を理解する

この章で学ぶこと

レガシープロジェクトとは何か
レガシーコードとレガシー基盤の例
レガシープロジェクトを作り出す組織の要素
改善計画

 こういうシーンに覚えがないだろうか。あなたは仕事場に出勤し、コーヒーを手に、最新の技術的ブログに目を通す。最初に読むのは、シリコンバレーのヒップな若い起業家が、ファッショナブルなプログラミング言語Xと、NoSQLデータストアのYと、ビッグデータツールのZを組み合わせて世界を変えるという話。けれども、あなたの気分は沈み込む。これらのテクノロジーを、自分の仕事に使ってみるような時間は、取れないだろう。製品を改善するために使うことなど、なおさら無理だろう、と思って。

 どうして、できないのか? それは、あなたが何億行もありそうな、テストもされず、ドキュメントもなく、とうてい理解できそうにないレガシーコードの保守を任されているからだ。そのコードは、あなたが最初にHello Worldを書いたときよりも前から製品化されていて、もう何十人もの開発者が入れ替わり立ち替わり、手を染めている。就業時間の半分は、コミットを検査して、何かリグレッションを起こしていないかチェックすることに費やされ、残りの半分は、避けようのないバグが侵入したため、その消火作業に費やされる。そして、一番気が滅入るのは、時間が経過するにつれて、コードベースにもっとコードが追加され、どんどん壊れやすくなり、問題が悪化していくことだ。

 けれども、絶望してはいけない。まず最初に、あなたが孤独ではないことを思い出そう。平均的な開発者は、新しいコードを書くよりも、ずっと多くの時間を、既存のコードの仕事に費やしている。そして開発者の大多数は、何らかの形でレガシープロジェクトを扱わなければならないのだ。第2、レガシープロジェクトには、最初はどれほど朽ち果てて見えても、必ず蘇生する希望があることを思い出そう。本書の目的は、まさにそれを行うことである。

 この最初の章では、我々が解決しようとしている各種の問題のサンプルを見て、蘇生のためのプランを立て始める。

第2章 スタート地点を見つける

この章で学ぶこと

リファクタリングの努力を、どこに集中させるかの判断
レガシーソフトウェアに対するポジティブ思考
ソフトウェア品質の計測
FindBugs、PMD、Checkstyleでコードベースを検査するインスペクション
Jenkinsによる継続的インスペクション

 第1章で、レガシーソフトウェアとは何であり、なぜそれを改善すべきなのかは明確になったと思う。この章では、改善策の立てかたと、その策を実施するときに進捗を測る方法を見ていく。

第2部 コードベース改良のためのリファクタリング

 第2章ではインスペクションの基盤技術をセットアップした。これで、レガシーソフトウェアの「リエンジニアリング」を開始するための準備が整った。

 第3章では、コードベースをリファクタリングするか、それとも捨て去ってゼロから書き直すリライトかという、非常に重要な選択について論じる。その判断は、ガイドとなる情報が足りないプロジェクトの初期段階で下されるので、しばしばリスクを伴う。そこで、よりインクリメンタルなアプローチによって、そのリスクを軽減する方法も学ぶ。

 第4章、第5章、第6章では、ソフトウェアのリエンジニアリングを行う3つの選択肢について詳しく述べる。その3つとは、リファクタリングと、リアーキテクティング(re-architecting)と、ビッグリライト(Big Rewrite)だ。これらは、ある意味では互いの変種みたいなものだが、作業対象のスケールが異なる。リファクタリングは、コードの構造をメソッドやクラスのレベルで変更する。リアーキテクティングは、モジュールやコンポーネントのレベルで行うリファクタリングだ。そしてビッグリライトは、可能な限り高いレベルで行うリアーキテクティングだ。

 第4章では、私がこれまでにしばしば自分で使って成功したか、あるいは成功するのを見たことがある、数々のリファクタリングパターンを紹介する。第5章では、モノリシックなJavaアプリケーションを、いくつもの相互に独立したモジュールに分割するケーススタディを提供するほか、モノリスとマイクロサービスのメリットを比較する。最後に第6章では、大きなソフトウェアのリライトを成功させるためのヒントを提供する。

第3章 リファクタリングの準備

この章で学ぶこと

あなたのリファクタリング計画に皆を参加させる
リファクタリングか、ゼロ(スクラッチ)から書き直すかを決める
リファクタリングする価値があるものとないものを区別する

 この章では、現実のコードベースに大規模なリファクタリングを実行するとき直面することが多い「技術的ではない問題」に目を向けよう。理想的な世界なら、美しいコードを作るのに完全な自由と無制限の時間を使えるだろうが、ソフトウェア開発の現実は、しばしば妥協を強いられるものだ。もしあなたがチームのメンバーとして働いていて、そのチームが、(計画と目標、予算と期限を持つ)大きな組織の一部であれば、あなたの同僚である技術者たちと、技術者ではない関係者たち(stakeholders)の両方から、進むべき最良の道についての同意を得るため、あなたの交渉術を発揮する必要があるのだ。

 親身に忠告するのだが、リファクタリングは常に、組織の目標を念頭に置いて行う必要がある。言い換えると、誰があなたに給料を払っているのかを忘れてはいけない。リファクタリングは、それがビジネスに長期的な価値をもたらすと、あなたが証明できるときにだけ行うべきだ。

 大きな改良プロジェクトに乗り出す前に、答えなければならない重要な質問のひとつは、リファクタか、それともリライト(書き直し)か、である。ソフトウェアの品質を、リファクタリングだけで、本当に満足できるレベルまで上げられるだろうか。それとも、ゼロからの書き直しのほうが賢明な選択だと言えるほど、そのソフトウェアは、どうしようもない状態なのだろうか。これは、最後には、あなたとあなたのチームが自分で答えなければならない質問だが、私もできるだけ、あなたが判断を下す助けになるように序言を提供しよう。また、完全なリライトにつき まとうリスクを軽減させるハイブリッドなアプローチも論じる。

第4章 リファクタリング

この章で学ぶこと

リファクタリングで規律を維持する方法
レガシーコードの「気になる匂い」と、それぞれの消臭術
自動テストでリファクタリングをサポートする

 この章では、レガシーコードとの戦いで最も重要な武器となるリファクタリングを見ていく。効果的なリファクタリングを行うために一般的なヒントを提供するほか、私が現実のコードで使うことの多い個々のリファクタリング技術も、いくつか紹介する。さらに、レガシーコード用にテストを書くためのテクニックも見ていくが、これはリファクタリング後に何も壊していないことを確認するうえで欠かせないものだ。

第5章 リアーキテクティング

この章で学ぶこと

モノリス的なコードベースを複数のコンポーネントに分割する
1個のWebアプリケーションをサービスのコレクションに分散する
マイクロサービスの長所と短所

 前章で見たリファクタリングのテクニックは、コーディングの段階で行う改善だった。リファクタリングでは、そこまでしか到達できないが、ときにはもっと大きく考える必要がある。この章では、ソフトウェアの構造全体を改善する方法を見ていこう。つまりソフトウェアを、より小さく保守しやすいコンポーネントに分割する方法だ。また、1個のアプリケーションを複数のサービス(ネットワークを介して通信するサービスあるいはマイクロサービス)に分割する方法についても、長所と短所を論じる。

レガシーソフトウェア改善ガイド

Amazon   SEshop   その他

レガシーソフトウェア改善ガイド

著者:クリス・バーチャル
監訳:吉川邦夫
発売日:2016年11月10日(木)
価格:4,104円(税込)

本書について

本書は単純な(でも難解な)クラスやメソッドレベルのリファクタリングから、モジュールあるいはコンポーネント全体を視野に入れた、広い範囲のリファクタリング。また、リライトに関するノウハウを紹介します。

第6章 ビッグ・リライト

この章で学ぶこと

書き換えプロジェクトの範囲を決める
既存のソフトウェアが新しい実装に与える影響
レガシーデータベースをどうするか

 あなたが「大いなるリライト」(The Big Rewrite)に挑戦するなら、他の選択肢をすべて試した後のことだと思いたい。あなたはコードベースのリファクタリングを試みたが、行き止まりに達した。レガシーソフトウェアをサードパーティ製ソリューションで置き換える方法についても、実現可能かどうか調べたが、あまりにも多くのカスタマイズが必要になって、ゼロから書くより仕事の量が多いことが分かった。リライト(書き換え)から逃れる手段はないと、あなたは結論を下した。それは鳥肌が立つような状況だ。

 自分はレガシーアプリケーションをゼロから書き換えるのだ、と覚悟すると、なぜ鳥肌が立つのだろうか。まずは、その理由を確認しておこう。第1に、そのプロジェクトは際限なく引き伸ばされるだろう。思ったより長くかかることを私が保証する。最初は、書き換えなど比較的単純な作業だと思われるかも知れない。既存のコードが行っていることを、ただ真似すればよいのだから。けれども、いったん実装を始めると、既存のソフトウェアには(実装にも、仕様にも)、あらゆる種類の隠れた特殊ケースや、不可解な抜け穴があり、そのすべてを調査し文書化する必要が生じる。これによってプロジェクトが停滞するだけでなく、しばらく続けていると飽き飽きしてしまうのだ。もちろん開発者は、たいがいコードを書きたくてしょうがないのだが、リライトの場合、その仕事の大部分が、レガシーソフトウェアの謎めいた振る舞いを解き明かし、それをどう扱うのが最良の策かを議論するために費やされてしまう。

 第2に、書き換えは、それに費やされる努力と困難が大きいのに、ソフトウェアのエンドユーザーに提供される直接的な価値が、あまりにも少ないことが、しばしばある。何か月もかけて構築したアプリケーションなのに、エンドユーザーから見ると、以前とまったく同様に動作するとしか思えない。それどころか、人々は既存のソフトウェアにあったバグや欠点に慣れてしまい、特徴のように思いがちだから、もしそれらを忠実に再現しないと、熱心なユーザーを失望させるリスクがある。さらに、あなたの新しい実装によって、独自の新しいバグが導入されることは、ほとんど確実である。

 とはいえ、ときにはリライトが本当に(悪い選択肢ばかりの中では)最良のオプションかも知れない。そうだとしたら、リライトをスムーズに進めるために考慮すべきことが、いくつかある。この章では、プロジェクトの範囲を決める方法を学び、新しいソフトウェアに対する既存の実装からの影響を、どこまで許せばよいのかを考慮し、レガシーデータベースを扱う戦略について検討する。

第3部 リファクタリングの先へ ― プロジェクトのワークフローと基盤を改善する

 この本の最後にあたる第3部では、これまでの「どういうソフトウェアを書くべきか」という話題を超えて、そのソフトウェアを「どうやってビルドし、保守するか」を考える。

 これは範囲の広いトピックで、ローカルマシンを効率的なソフトウェア開発のためにセットアップする方法から、ソフトウェアを実行する必要のある複数の環境を管理し、チーム作業のためにバージョン管理システムを使い、ソフトウェアを迅速かつ信頼できる方法で製品にデプロイする方法まで含まれる。

 今後の3章では、Vagrant、Ansible、Gradle、Fabricなど、かなり多くのツールを紹介する。これらを今までに使ったことがなくても、あるいは同じ仕事をする同様なツールを使って満足していても、心配は無用だ。これらを使うのは、ただ基本的なテクニックを学べるように具体的な例を示すためなのだ。同様に使える他のツールについての情報も、随時紹介しよう。

 そして最後の章では、今日あなたが書くソフトウェアが、明日には悲惨なレガシーになる、というホラーストーリーを防ぐためのヒントを提供する。

第7章 開発環境を自動化する

この章で学ぶこと

優れたREADMEファイルの価値
VagrantとAnsibleを使って開発環境を自動化する
外部リソースへの依存性を排除して、開発者の自立性を高める

 ほとんどすべてのソフトウェアは、何らかの形で周囲の環境に依存する。実行されるマシンの上で、ある特定のソフトウェアが実行されることや、ある特定の構成が設定されることを、ソフトウェアは(というより、それを開発した人は)期待している。たとえば多くのアプリケーションは、データの保存にデータベースを使うから、どこかでデータベースサーバーが実行され、それをアクセスできることに依存する。構成に対する依存の例としては、ログファイルを保存するために特定のディレクトリの存在を期待するソフトウェアがある。

 これらの依存性をすべて調べ、それらを満足させる環境を用意するのは、とても面倒な作業になりかねない。依存性は十分に文書化されていないことが多いが、その理由はおそらく単順で、ドキュメントを置くのに適した場所か、標準のフォーマットが、存在しないからだ。

 この章では、あなたが(そして他の人々が)開発環境をセットアップしてレガシーソフトウェアの保守を開始するまでの作業を、できるだけ簡単にする方法を調べよう。ここで書くスクリプトは、プロビジョニング(provisioning)のプロセスを自動化するだけでなく、ドキュメントを残す役割も果たすので、後に保守を行う人たちがソフトウェアの依存性を理解するのが容易になる。

第8章 テスト、ステージング、製品環境の自動化

この章で学ぶこと

Ansibleを使って複数の環境にプロビジョニングする
開発基盤をクラウドに移す

 前章ではUADアプリケーション用のローカル開発環境に自動的なプロビジョニングを行う、Ansibleのplaybookを書いた。この章では、開発マシンから製品サーバーにいたる全部の環境へのプロビジョニングに再利用できるよう、そのAnsibleスクリプトのリファクタリングを行う。

 実際に作業を始める前に、ソフトウェアを実行させる必要のある環境には、どのようなものがあるのか、また、それらの環境へのプロビジョニングを、なぜ自動化したいのかを、簡単にまとめておこう。

 アプリケーションの開発と実行に、どのような環境が必要かは、ケースによって微妙に異なるが、一般的な要件は次のものだろう。

  • 開発環境―開発者のローカルマシン。これをDEV環境と呼ぼう。
  • テスト環境―ソフトウェアのテストを、現実的なデータを使って、製品で使われるのと同様なハードウェアで実行する環境。ニーズによっては複数の目的に複数のテスト環境が必要になるかも知れない(ひとつは日常的な手作業によるテスト用、ひとつは最終的なステージング用、もうひとつは性能テスト用など)。この章ではテスト環境が1つだけであると想定し、それをTESTと呼ぶ。たとえ準備が必要な環境がいくつあっても、原則は同じである。
  • 製品環境―実際にユーザーがソフトウェアとやりとりするのが製品の環境だ。もしソフトウェアが、ネイティブなモバイルアプリや、ユーザー自身がホスティングするビジネスソフトのようなものであれば、この環境には我々の制御がおよばないので、準備に関わる必要はない。けれども、あなた自身がホスティングするWebアプリケーションのようなものなら、あなたが製品環境を制御するのだから、プロビジョニングを行う責任があるはずだ。この章では後者を想定して、その環境をPRODと呼ぶ。

 もちろん実際には、たとえばライブラリのように、それ自身が実行されるのではなく、実行されるソフトウェアの一部を構成するようなソフトウェアも存在する。ただし、そういう場合であっても、独立したTEST環境を持って、その中で統合テストを実行し、そのライブラリが、あるアプリケーションの一部として正しく機能することをチェックするのは有益なことだろう。

第9章 レガシーソフトウェアの開発/ビルド/デプロイを刷新する

この章で学ぶこと

開発とビルドのツールチェインをレガシーから切り替える
Jenkinsを使ってレガシーソフトウェアを継続的に統合する
製品のデプロイメントを自動化する

 これまでの2章で見たプロビジョニングは、レガシーソフトウェアが依存するものを、すべてインストールして設定するものだった。ここで話をソフトウェアそのものに戻し、ツールチェインとワークフローに少し労力を費やすことでレガシーソフトウェアの保守を容易にする方法を紹介しよう。

第10章 レガシーコードを書くのはやめよう!

この章で学ぶこと

これまでに習ったテクニックを、レガシーコードだけでなく新しいコードにも応用する
使い捨てにできるコードを書く

 もう読者は、どんな「放置されたレガシーコード」を継承しても、その扱い方や、健康な状態に戻す術を知っているはずだ。我々はリライトも、リファクタリングも、継続的インスペクションも、ツールチェインの刷新も、自動化も、まだ他にも、さまざまなことを見てきた。けれども、たぶんあなたには新しいコードを書く時間も、少しはあっただろう。すべてのコードは、いつかレガシーになる運命なのだろうか? それとも、いまあなたが書いているコードが数年後に誰かの悪夢になることを、予防する手段があるだろうか?

 これまでの9章で、我々は非常に広い範囲を扱ってきたが、いくつかのメインテーマが(明示的に書かれた場合も、暗黙的に推測される場合も含めて)本書のいたるところに現れていた。それらのアイデアは、これまでレガシーコードの文脈で論じてきたが、多くは新規プロジェクトにも同じように適用できる。この最後の章で総括する、それらのテーマとは、次のものだ。

  • ソースコードがすべてではない
  • 情報はフリーになりたがらない
  • われらの仕事は終わらない
  • すべてを自動化せよ
  • 小さいのが美しい

 これらのテーマに関する詳細を論じ、過去・現在・未来に渡るレガシー対処法を提示する。

レガシーソフトウェア改善ガイド

Amazon   SEshop   その他

レガシーソフトウェア改善ガイド

著者:クリス・バーチャル
監訳:吉川邦夫
発売日:2016年11月10日(木)
価格:4,104円(税込)

本書について

本書は単純な(でも難解な)クラスやメソッドレベルのリファクタリングから、モジュールあるいはコンポーネント全体を視野に入れた、広い範囲のリファクタリング。また、リライトに関するノウハウを紹介します。

  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

  • 渡部 拓也(ワタナベ タクヤ)

     翔泳社マーケティング課。MarkeZine、CodeZine、EnterpriseZine、Biz/Zine、ほかにて翔泳社の本の紹介記事や著者インタビュー、たまにそれ以外も執筆しています。

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5