レガシーコード読書会 20120618

73
レレレレレレレレレレレレレレレ 2012/06/18 CyberX レレレレレ レレレレ

Upload: suguru-shirai

Post on 28-May-2015

683 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: レガシーコード読書会 20120618

レガシーコード改善ガイド読書会第1回

2012/06/18CyberX エンジニア 石川泰式

Page 2: レガシーコード読書会 20120618

まえがき

•最初はプログラマの心の中でけがれのない水晶のように輝いていた設計が,時間が経つことで劣化し,悪くなった肉のように腐敗していく

Page 3: レガシーコード読書会 20120618

まえがき

•最初に必要だと言ったもので顧客が満足してくれさえすれば,設計は問題なかったはずだ,と考えて自分を慰める

•要求を変えてくる顧客がいけない

Page 4: レガシーコード読書会 20120618

まえがき

•「要求変更が発生しました」要求の変更に耐えられない設計は,そもそも悪い設計です

•優秀なソフトウェア開発者は皆,変更に耐え得る設計を目指している

Page 5: レガシーコード読書会 20120618

まえがき

•これはどうにも困難な課題に思える•実際あまりに困難なため,これまでに開発されたほとんどすべてのシステムがゆっくりと衰弱し腐敗していく

•この腐敗したプログラムを「レガシーコード」と特別な名前と名付けた

Page 6: レガシーコード読書会 20120618

まえがき

•プログラミングの最初の喜びが強烈だったとしても,レガシーコードに取り組む苦痛のせいで,その炎が消されてしまうことも少なくない.

Page 7: レガシーコード読書会 20120618

まえがき

•私たちの多くは,コードがレガシーになることを「防ぐ」方法を探し続けてきた.

•Michael Feathersは,私たちの多くが見落としていた点を見抜いた.

Page 8: レガシーコード読書会 20120618

まえがき

•それは,防ぐだけでは不十分だということ

•腐敗を防ごうとするだけでは不十分であり,逆戻りさせる必要がある.

Page 9: レガシーコード読書会 20120618

まえがき

•本書で取り上げるテーマは,腐敗を逆戻りさせる方法

Page 10: レガシーコード読書会 20120618

まえがき

•絡み合った,不透明で入り組んだシステムを,ゆっくりと,徐々に,1つずつ,1歩ずつ,簡素できちんと構造化された,優れた設計に変えていくための本

•エントロピーを逆転させる.

Page 11: レガシーコード読書会 20120618

まえがき

•腐敗を逆戻りさせるのは簡単ではないし,すぐにできることもない.

•Michaelが本書で紹介している手法やパターンやツールは有効だが,それには手間と時間と忍耐力,そして慎重さが必要

Page 12: レガシーコード読書会 20120618

まえがき

•本書は魔法の弾丸ではない.•システムに積りに積もった腐敗を一晩で取り去る方法は教えてくれない

Page 13: レガシーコード読書会 20120618

まえがき

•本書には今後仕事を続けていく上で役立つ,規律や概念や姿勢が書かれている

•まさにそれによって,徐々に質の落ちていくシステムを,徐々に質の向上するシステムに変えていく事ができる

Page 14: レガシーコード読書会 20120618

はじめに

•コンピュータで何かを動かすという純粋な喜びを経験したことがありますか?

Page 15: レガシーコード読書会 20120618

はじめに

•プログラマに尋ねてみたところ,ほとんどが経験していた.

Page 16: レガシーコード読書会 20120618

はじめに

•その喜びは私たちがこの仕事に就いた理由の1つのはずですが,日常のどこに埋もれてしまったのでしょうか?

Page 17: レガシーコード読書会 20120618

はじめに

•頑張ってはいるものの,スケジュールのプレッシャーからか,過去のしがらみからか,自分の仕事の見本となる優れたコードがないためか,多くの人がレガシーコードを書いてしまっている

Page 18: レガシーコード読書会 20120618

はじめに

•レガシーコードとは,誰かから引き継いだコード

Page 19: レガシーコード読書会 20120618

はじめに

•簡単なはずの機能追加をしようとして徹夜したことや,士気を喪失してまったこと,チーム全員がコードにうんざりしてどうでもよくなってしまった感覚,死んでしまいたくなるようなコードを思い出すでしょう.

Page 20: レガシーコード読書会 20120618

はじめに

•そのコードを改善しようと考えることすら嫌な気持ちになるかもしれない

•そんな手間をかけるのは無駄に思えるから

Page 21: レガシーコード読書会 20120618

はじめに

•レガシーコードとは,単にテストのないコード

Page 22: レガシーコード読書会 20120618

はじめに

•テストのないコードは悪いコードである•どれだけうまく書かれているかは関係ない•どれだけ美しいか,オブジェクト指向か,きちんとカプセル化されているかは関係ない

Page 23: レガシーコード読書会 20120618

はじめに

•テストがあれば,検証しながらコードの動きを素早く変更することができる.

•テストがなければ,コードが良くなっているのか悪くなっているのかが本当にはわからない.

Page 24: レガシーコード読書会 20120618

はじめに

•きれいなコードは有益だが,それだけでは不十分

•テストなしに大規模な変更をしようとすると,チームは危険な賭けに出ることになる.

Page 25: レガシーコード読書会 20120618

はじめに

•チームの腕が上がって,より明確なコードを書き始めたとしても,古いコードがきれになるのには時間がかかる.

•たいていの場合,完全にきれいになることはありえない.

Page 26: レガシーコード読書会 20120618

はじめに

•本書で説明する手法は,かなり大きいコードでテストしてある.例が小さいものになっているのは,本のスペースの都合のため.特に次のようにコードの中に省略記号( ...)が含まれている時は,「汚いコードがここに 500行入る」と読み替えて下さい.

Page 27: レガシーコード読書会 20120618

はじめに

•本書は美しいコードを書くための本でも,美しい設計をするための本でもない.

•優れた設計を目指すべきではあるが,レガシーコードにおいては,不連続ないくつものステップへ経なければそこには到達できない.

Page 28: レガシーコード読書会 20120618

はじめに

• 本当に必要なのは,ありのままの患者を受け止め,悪いところを直し,より良い健康状態にすること

• コードをより健康に,より作業しやすくすることは可能

• 患者の状態が少し回復したら,その後で,より健康的な生活が送れるよう患者を手助けする

Page 29: レガシーコード読書会 20120618

はじめに

•ちょっと落ち着いて楽になれるところまで持って行きたい

•私たちはそれを望み,コードの変更を楽にしようと頑張っている.

•チームがその意識を持ち続けることができれば,設計は良くなる.

Page 30: レガシーコード読書会 20120618

はじめに

•本来プログラミングは非常にやりがいのある,楽しい仕事のはず

•日々の仕事の中でそのように感じられずにいる人が,本書の手法によってその気持を発見し,チームに広げてくれることを望んいでいます.

Page 31: レガシーコード読書会 20120618

はじめに

•本来プログラミングは非常にやりがいのある,楽しい仕事のはず

•日々の仕事の中でそのように感じられずにいる人が,本書の手法によってその気持を発見し,チームに広げてくれることを望んいでいます.

Page 32: レガシーコード読書会 20120618

第1部変更のメカニズム

Page 33: レガシーコード読書会 20120618

第1章ソフトウェアの変更

Page 34: レガシーコード読書会 20120618

ソフトウェアの変更

•コードの変更は素晴らしいこと•私たちの日々の生活を困難なものにしてしまうコードの変更方法はいくらでもある.

•逆に楽にできる方法もいくらでもある.

Page 35: レガシーコード読書会 20120618

ソフトウェアの変更

•本書では,その議論を少し広げて,非常に厄介な状況のコードに取り組む方法について考えてみる.

•そのために,まず変更のメカニズムについて掘り下げてみる.

Page 36: レガシーコード読書会 20120618

1.1 ソフトウェア変更の4つの理由

•話を簡単にするために,ソフトウェア変更の理由を大きく4つに分けて検討する.

•要件の追加•バグの修正•設計の改善•リソース利用の最適化

Page 37: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•要件の追加は,変更の理由の中で一番わかりやすいものと言える

•ソフトウェアが実現する,ある動作に対して,別の動作も行ってほしいとユーザーが言う場合である.

Page 38: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•マネージャが左側にある会社のロゴを右側に移してほしいといったとする.

Page 39: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•しかし話を聞いてみると,実現するのがそれほど簡単ではないと気づく.

•マネージャはロゴの移動だけでなく,次のリリースではユーザの操作に応じてロゴの表示を動的に変化することを望んでいた.

Page 40: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•これはバグ修正?それとも要件追加?

Page 41: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•顧客の立場からすると,マネージャは紛れもなく問題の修正を依頼している.

•開発者の立場からすると,この変更は完全に新しい要件とも取れる.

Page 42: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•見方によっては,要件追加かバグ修正かは終わりのない議論かもしれない.

•結局はコードやその他の成果物を変更することに変わりはない.

•残念ながら,バグ修正か要件追加かの議論によって,技術的にもっと重要なことが隠されてしまっている.

Page 43: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•それは振る舞いが変更されるかどうかである•新しい振る舞いの追加と,既存の振る舞いの変更には大きな違いがある.

Page 44: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•ソフトウェアで最も大切なのは「振る舞い」であり,振る舞いこそがユーザの求めるものである.期待される振る舞いを私たちが追加すればユーザは喜ぶが,ユーザの求める振る舞いを変更,あるいは削除してしまえば,バグの作り込みとなり,私たちの信頼は失われてしまう.

Page 45: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•会社のロゴの例は振る舞いの追加?•答えはイエス•なぜならその変更によって,システムはページの右側にロゴを表示するようになるから

Page 46: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•振る舞いの削除?•答えはイエス•なぜなら左側のロゴがなくなるから

Page 47: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

public class CDPlayer { public void addTrackListing(Track track) { ... } ...}

Page 48: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•このクラスには,曲目リスト( TrackListing)を追加するメソッドが定義されている.

•ここに曲目リストを置き換えるメソッドを追加する.

Page 49: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

public class CDPlayer { public void addTrackListing(Track track) { ... }

public void replaceTrackListing(Track track) { ... } ...}

Page 50: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•このメソッドの追加は,新しい振る舞いの追加だけか?それとも変更か?

•答えはどちらもノー•メソッドを追加するだけで,どこからも呼び出されなければ振る舞いは変化しないから

Page 51: レガシーコード読書会 20120618

1.1.1 要件の追加とバグの修正

•ある程度の変化なしに振る舞いを追加することはほとんど不可能と言える.

Page 52: レガシーコード読書会 20120618

1.1.2 設計の改善

•設計の改善は,別の種類のソフトウェア変更•保守しやすくなるようにソフトウェアの構造を変更する時,通常は振る舞いを同じに保つ必要がある.

•もし,その過程で必要な振る舞いが失われてしまえば,それはバグと呼ばれることになる

Page 53: レガシーコード読書会 20120618

1.1.2 設計の改善

•多くのプログラマがあまり設計を改善したがらないのは,その過程で振る舞いを失ってしまったり,間違った振る舞いを作りあげてしまいやすいから

•振る舞いを変えずに設計を改善することをリファクタリングと呼ぶ.

Page 54: レガシーコード読書会 20120618

1.1.2 設計の改善

•リファクタリングの基本として,変更前と変更後で振る舞いが変わらないことを確認するためのテストを書き,検証しながら少しずつ作業を進めることで,ソフトウェアの保守性を向上できるという考え方がある.

Page 55: レガシーコード読書会 20120618

1.1.2 設計の改善

•リファクタリングは,ただソースコードの書式を修正するようなリスクの低い作業ではない

•リスクを顧みずに大規模にソースコードを書き直す作業でもない

Page 56: レガシーコード読書会 20120618

1.1.2 設計の改善

•リファクタリングでは小さな構造修正を繰り返し行う

•その際,容易に変更を行えるようにテストでサポートする.

•変更という面から見て重要なのは,リファクタリング時には機能を変更すべきではないということ

Page 57: レガシーコード読書会 20120618

1.1.3 リソース利用の最適化

•リソース利用の最適化はリファクタリングと似ているが,目的が異なっている.

•最適化における変更するものは,プログラムが使用しているなんらかのリソース(通常は時間やメモリ)に相当する.

Page 58: レガシーコード読書会 20120618

1.1.4 4つの変更のまとめ

要件追加 バグ修正 リファクタリング 最適化

構造 変化する 変化する 変化する ー

新機能 変化する ー ー ー

機能 ー 変化する ー ー

リソース利用 ー ー ー 変化する

Page 59: レガシーコード読書会 20120618

1.1.4 4つの変更のまとめ

•要件追加,リファクタリング,最適化のいずれでも,既存の機能は変わらずに保たれる

•実際には,バグの修正の場合でも,詳しく調べてみると,機能を変更するものの,変更されない既存機能に比べると,変更量はごくわずかな場合がほとんど

Page 60: レガシーコード読書会 20120618

1.1.4 4つの変更のまとめ

•要件追加やバグ修正は,リファクタリングや最適化とよく似ている.

•4つのいずれの場合でも,一部機能や一部振る舞いを変更するが,元のままに保たれている部分のほうがずっと多い

Page 61: レガシーコード読書会 20120618

1.1.4 4つの変更のまとめ

既存の振る舞い 新しい振る舞い

Page 62: レガシーコード読書会 20120618

1.1.4 4つの変更のまとめ

•変更を行った時に何が起きるかを,整理する良い面は,何に集中するべきかがわかりやすくなること

•悪い面は,集中すべきは変更箇所だけではない.厄介なことにコードに触れていないからと言って,振る舞いが変わらない保証はない

Page 63: レガシーコード読書会 20120618

1.1.4 4つの変更のまとめ

•変更時には,対象箇所以外の振る舞いが変っていないことを確認する必要があるが,それはとても困難な作業

•しばしば問題となるのは,ある変更によってどれだけの振る舞いに影響が及ぶかを把握できないこと

Page 64: レガシーコード読書会 20120618

1.1.4 4つの変更のまとめ

•変更を安全に行うために最も重要なことは,影響範囲を理解すること

Page 65: レガシーコード読書会 20120618

1.1.4 4つの変更のまとめ

•既存の振る舞いを変えずに保つことは,ソフトウェア開発における最も困難なことの1つである.主要な機能を変更をしようとする時でさえ,通常は既存の振る舞いの大部分を変更せずに保たれなければならない.

Page 66: レガシーコード読書会 20120618

1.2 危険な変更

•振る舞いを保つのは非常に困難なこと•変更を行いながら振る舞いを維持する作業は大きなリスクを伴う

Page 67: レガシーコード読書会 20120618

1.2 危険な変更

• リスクを緩和するには,次の3つの点を考慮する必要がある.

• どんな変更を行わなければならないか• 変更が正しく行われたことをどうすれば確認できるか

• 何も壊していないことをどうすれば確認できるか

Page 68: レガシーコード読書会 20120618

1.2 危険な変更

•変更を避けることでソフトウェアの問題を最小限に抑えられるという考え方は魅力的だが,残念なことに必ず問題は付きまとう

Page 69: レガシーコード読書会 20120618

1.2 危険な変更

•良いシステムでは調べることで安心でき,これから行う変更に確信を持てる

•悪いコードでは,物事を調べた後で変更に取り掛かる時には,虎から逃げるために崖から飛び降りるような気持ちになる

Page 70: レガシーコード読書会 20120618

1.2 危険な変更

•大きなクラスを分割する作業は,週に2,3回ぐらい行ってない限り,極めて困難な仕事になりがち

•頻繁に変更を行っていれば,日常業務になる•何が分割できて,何ができないかの見当を付けやすくなり,変更作業もずっと容易になる

Page 71: レガシーコード読書会 20120618

1.2 危険な変更

•変更の回避は恐怖をもたらす.•不幸なことに,多くのチームが変更に対して信じがたいほどの恐怖を抱いていて,その恐怖は日に日に強くなっていく.

Page 72: レガシーコード読書会 20120618

1.2 危険な変更

•他の方法として,やみくもに頑張るというのがある.人を増やして,机に向かって分析する時間を確保し,すべてのコードを調べ尽して「正しい」やり方で変更を行うこともできる.

•時間をかけてじっくり精査すれば,変更は安全に行えるはず.

Page 73: レガシーコード読書会 20120618

1.2 危険な変更

•しかし,これは本当だろうか•すべての作業を終えた後で,精査が正しかったかどうかを判断できる人などいるのか?