「レガシーコードからの脱却」を読んで
本記事では私が読んだ「レガシーコードからの脱却」について、紹介したいと思います。
本書の概要
情報 | 説明 |
---|---|
出版社 | オライリージャパン |
タイトル | レガシーコードからの脱却 ―ソフトウェアの寿命を延ばし価値を高める9つのプラクティス |
発売日 | 2019/9/19 |
著者名 | David Scott Bernstein |
購入ページ | こちら |
本書を手に取ったきっかけ
オファー面談時に「入社するにあたり学習すべきことは何か」を聞いたところ、面接官の方が「レガシーコードからの脱却」というワードをおっしゃっていました。
ネットで色々探したところピッタリなタイトルの本を見つけたので購入しました。
各章で個人的に気になったところ
1章 何かが間違っている
- レガシーコードとはテストができないコードと言い換えることもできる。
- 従来のウォーターフォール方式の開発は機能をまとめてリリースするので非効率かつレガシーコードの温床となる。
- ソフトウェア業界は基本原則や共通ルールが確立されていない。
2章 CHAOSレポート再考
- CHAOSレポートとはスタンディッシュグループが作成した広範囲のソフトウェア開発の成功率を評価したものである。
- CHAOSレポートは品質面や顧客満足度などの指標は度外視されている課題がある。
- 破綻したソフトウェア開発の損失について、アメリカでは毎年100億ドル近く損失が出ている。
(日本ではこんな記事が出ていましたね。。。)
3章 賢人による新たなアイデア
- アジャイルの開発手法はウォーターフォール方式に代わる選択肢であり、繰り返し小さい規模の開発を繰り返すことで、開発コストの削減につなげることを目的としている。
4章 9つのプラクティス
- 次章以降で紹介されている9つのプラクティスの前説なので割愛。
5章 プラクティス1 やり方より先に目的、理由、誰のためかを伝える
- ソフトウェア開発において、やり方をよりも目的や対象者を意識することで、一つのやり方に固執することなく、最適解を得ることができる。
- 受け入れ基準を明確化させる(何をするはずか/いつ動くのか/どうなったら私達は次に進めるのか)ことで、例外やエラー処理に集中することができる。
- 受け入れ基準の明確化にはSpecFlowやFIT、Cucumberといったテストツールの利用も効果的。
6章 プラクティス2 フィードバックサイクルを短くする
- サイクルタイムとは仕掛かり中のタスクの数をすべての作業を終わらせるのにかかる時間で割って算出する。すなわち仕掛かり中のタスクを減らせば減らすほど、リリースサイクルを短くすることができる。
- 開発者が受けるフィードバックは顧客から受けるものだけではなく、自動テストの実行結果やビルド結果も含まれる。ビルドを高速化させることで、フィードバックサイクルを短くすることができる。
- ソフトウェア開発において価値を計測するには以下の指標が有効。
- 価値実現までの時間
- コーディングに使った時間
- 欠陥密度
- 欠陥検出までの時間
- 機能ごとの顧客価値
- 機能を提供しない場合のコスト
- フィードバックループの効率
7章 プラクティス3 継続的に統合する
- 開発における真の完了はローカル環境で動かして完了するのではなく、ビルド環境にマージし、理解しやすく、読みやすく、保守可能である状態にする状態である。
- ビルドを自動化する仕組みを作ることで継続的に統合しやすい環境を作ることができる。そのためには良いユニットテストを書く必要がある。
8章 プラクティス4 協力しあう
- プログラミングにおける協働方法は以下のようなものがある。
- ペアプログラミング:二人の開発者が一つのコンピューターで協働すること。
- バディプログラミング:ペアプログラミングを一部の時間でやること。
- スパイク:未知の課題解決のために複数の開発者が集まって一つのタスクをこなすこと。
- スウォーミング:複数のメンバー/チーム全体が集まって、障害対応など同一の問題解決に取り組むこと。
- モブ:日常的にチーム全体で同じ課題解決をすること。
- 協働を進めることで情報共有が円滑に進み、知識やスキルが広がる。
9章 プラクティス5 「CLEAN」コードを作る
- 「CLEAN」コードとは以下のような定義である。
- Cohesive(凝集性)
- Loosely Coupled(疎結合)
- Encapsulated(カプセル化)
- Assertive(断定的)
- Nonredundant(非冗長)
- 上記「CLEAN」を実現するには、テストしやすいコードが求められる。
10章 プラクティス6 まずテストを書く
- テスト駆動開発を実現するためには、開発者が小さい機能のテストを書いてから実装するというテストファースト開発の形式を取るのが望ましい。
- テスト駆動開発はすばやいフィードバックをもたらし、リファクタリングをサポートする。
11章 プラクティス7 テストで振る舞いを明示する
- テストファーストを実現するには以下のような流れで開発を行う。
- 正常系のテストコードを書く。
- クラスやメソッドのスタブコードを生成する。
- 正常系の処理を実装する。
- 異常系のテストコードを書く。
- 異常系の処理を実装する。
- テストコードは極力ミニマムな単位で実装する。(冗長にしない。)
- 似たようなシナリオで動くか、呼び出す順序が正しいか図るにはモックを使ったワークフローテストが有効である。方法は様々なものがある。
12章 プラクティス8 設計は最後に行う
- 持続可能な開発(=レガシーコードにしない)を実現するためには、以下のようなプラクティスを実践すると良い。
- コメントアウトされたコードや呼び出されないコードは消す。
- メソッドやクラス名を意味のわかりやすい名称に変える。
- 循環複雑度を減らす。
- ポリモーフィズムを利用し、再利用しやすいソースコードにする。
13章 プラクティス9 レガシーコードをリファクタリングする
- リファクタリングは以下のようなテクニックを用いると良い
- ピンニングテスト:数百から数千にわたるソースコードで書かれた単一のアクションに対する粒度の荒いテスト。
- 依存性の注入:Springなどのフレームワークを導入することで、依存性を注入する。
- ストラングラーパターン:古いサービスをラッピングする形で新しいサービスを作り、古いサービスを淘汰するまで繰り返すこと。
- 抽象化によるブランチ:開発中の実装にフィーチャーフラグをつけて、開発が完了したらフラグを取り、リリースする。これにより、ブランチが大量にできることを防ぐ
14章 レガシーコードからの学び
- まとめ的な章なので割愛。
感想
本書は大学の教科書で云うところの総論に当たるような位置づけにあたるのかなと思いました。
具体的な手法に関しては、各々別の教材で学習した方が良いと思います。(例えばユニットテストであれば、JUnitなど)
ただ何をすれば良いか、何を学習すれば良いかの指針作りにはとても良いのかと思いました。
そもそも今まではコーディングがナンボで、テストはコーディングが終わってからみたいな世界だったので、そんな自分からすれば新鮮な内容でした。
本書はプロジェクト管理・統制的な要素のことも書かれているので、立場が変わったら再度読んでみたいです。
初めてQiita記事を書いてみて
最初は何を書こう、役に立つものを書かないとと悩んでしまいましたが、書いているうちに自己理解や備忘録的な感じで使えばいいのかなと思いました。今回本の内容をまとめたのも、本の内容理解が目的です。
今後もこんな感じで書いていければと思います。