Showing 10 Result(s)

レガシーコードからの脱却 まとめ – 14.2

14.2 不要な出費はしない 内容 保守性に注力し「CLEAN」でテスト可能なコードを書くことが、ソフトウェアを保守するにも拡張するにもコストを下げる唯一の方法だ。 開発チームの中には、テスト駆動開発(TDD)をしておらず、QAプロセスをあてにして、開発者がコードに関するフィードバックをもらうのに2週間もかかるチームもある。そしてバグを修正するために数週間前に書いたコードを思い出す。そのために開発者の1日のほとんどを費やすようになる。同じバグならTDDで数秒でバグを直すほうが、よほど安くて済む。 本書でも言ったがQAが不要というわけではない。しかし、QAプロセスで品質を保証するだけよりも、良いプラクティスを使って品質を作り出すことに取り組もう。 学び CI/CD、ペアプロ、TDDなどのプラクティスは品質につながるものだが、最終的にランニングコスト削減につながる。ランニングコストが減るから続けることができる。 テストを自動化しリファクタリングしやすい状況を作り、リファクタリングして保守しやすいコードを作り、減った改修コストで更にテストとリファクタリングをする、というサイクルを作る努力をしよう。 学びを活かすアイディア・行動 CI/CD環境構築 テストコードの運用 簡単な案件のペアプロでペアプロ力を増やす

レガシーコードからの脱却 まとめ – 14.1

14.1 もっと良く速く安く 内容 アジャイルプラクティスの各種効果事例を紹介している。 それらによりテスト駆動開発(TDD)は「テストも書くのでコードは倍書くが、質もスピードも上げることができる」と論理付けている。開発者はコーディングとテストに時間を費やしているわけではない。仕様書の解読、ドキュメント作成、会議出席にも時間を費やすし、いちばん多くの時間を浪費しているデバッグ。 TDDはバグを意図的に発生させ修正しながら進める。「それがバグであること」と「修正が正しいこと」を仕様となるテストコードで担保しながら開発を進める。そしてコード変更のたびにテスト実行するため、後で意図しないバグ発生を抑え、デバッグの時間を減らすことができる。 生産性を向上させるのに、品質低下の犠牲を払う必要はない。 以下、論文や調査事例を紹介。 QSMA社によるアジャイルプラクティス導入効果調査 ウォーターフォール 欠陥率が大規模チームであるほど高い。 平均の4倍以上の場合もある。 XP、スクラム 欠陥率が平均より30%〜50%減。 論文:Realizing Quality Improvement Through Test-driven Development: Results and Experiences of Four Industrial Teams(テスト駆動開発を通じた品質向上の気づき:4つの事業チームの事例から) 調査対象のTDDを実践しているすべてのチームが欠陥密度の大幅な低下を示し、「テスト駆動開発は開発チームは生産性を大幅に減らすことなく、開発したソフトウェアの欠陥密度を大幅に減らす」ことができるとしている。 IBMのチーム → 40%減 マイクロソフトのチーム → 60%〜90%減 論文:Evaluating the Efficacy of Test-Driven Development: Industrial Case Studies(テスト駆動開発の有効性評価:業界事例) 同じ組織で、TDDを使ったプロジェクトと使っていない似たようなプロジェクトで、使った方がコード品質が2倍以上良い。 ノースカロライナ州立大学のボビー・ジョージとローリー・ウィリアムズによる2つのソフトウェア開発者のグループ調査 テスト駆動開発者は 高品質なコードを生み出した 18%多くブラックボックステストをパス 開発できる時間が16%も長くなったにも関わらず、テスト駆動開発者のテストケースは平均「メソッドの98%、命令文の92%、分岐の97%のカバー」を達成。 開発者の92%が「テスト駆動開発は高品質なコードを生み出す」と信じていることもわかった Exploring Extreme Programming in Context: …

レガシーコードからの脱却 まとめ – 13.10

13.10 本章のふりかえり 内容 13章の内容のふりかえり。 効果的なリファクタリングの観点 オープン・クローズドの原則 機能追加する場合、変更前に変更するためのリファクタリングをする DIできるようにするところを目指す ストラングラーパターンでシステムをリファクタリングする 機能追加の前準備と、実際の機能の追加を切り離すことで、作業が大幅に単純化され、バグ発生リスクが減る 学び なし 学びを活かすアイディア・行動 なし

レガシーコードからの脱却 まとめ – 13.9.2

13.9.2 いつリファクタリングを行うかについての7つの戦略 内容 リファクタリングできるコードはかなり多いはずだ。基本的に触ることもないし、拡張する必要もないコードはリファクタリングしなくてもよい。ここでは何をいつリファクタリングすれば効果的なのかを判断するための7つの戦略を紹介。 戦略 説明 重要なコードがうまく保守されていないとき 明らかに主要機能で、今後も修正は見込まれるけど、複雑になりすぎている場合。まずはテストコードから追加しよう。 コードを理解している人がいなくなったとき いなくなる前に、関連コードを修正する場合は、そのキーパーソンがクリーンアップしよう。基本全員が扱える状態を目指そう。 新しい情報によって、より良い設計が見つかったとき 今の設計を改修するコストよりもメリットが大きい場合リファクタリングが選択肢となる。 バグを修正するとき テストがなかったからバグが発生したと考えることができる。テストを書いてついでにリファクタリングするとよいだろう。 新機能を追加するとき 安全に機能追加する方法は、まず機能追加できるようにリファクタリングしてから機能追加すること。 レガシーコードのドキュメントを書くとき 難解なコードを理解するためのドキュメントに起こすとき。製造中であれば設計を見直し、リファクタリングできるか検討しよう。 作り直すより安いとき 同じような開発プロセスで作り直す場合、高い確率で同じような技術的負債を産む。リファクタリングをプロセスに組み込む方が安くなるか検討しよう。 学び リファクタリングできるタイミングは意外と多い 学びを活かすアイディア・行動 何をいつリファクタリングできるか整理 リファクタリング内容と関連しているコードの整理

レガシーコードからの脱却 まとめ – 13.9 – 13.9.1

13.9 実践しよう 13.9.1 リファクタリングから価値を得るための7つの戦略 内容 リファクタリングから効果的に価値を得るための7つの戦略を紹介。 戦略 説明 既存のシステムを学ぶ わかりにくいところは全部反面教師。 小さく改良する メソッド、クラスの移動、名前変更はツールで安全にできる。これを先にやるとロジックの修正がしやすくなる。 レガシーコードをテストで改良する リファクタリングは後々の開発コストを減らすことができる。テストはリファクタリングを安全にサポートする。まずテストを書こう。 クリーンアップしながら進める 開発を進める中、常にリファクタリングは行おう。 詳細がわかったら実装を再設計する 既存の設計では実現が難しい場合や、明らかに既存設計より良い設計が出た場合、今後を見越して再設計実施を検討する。 進む前にクリーンアップする 動作確認したら次に進む前にかならずリファクタリングする。 やってはいけないことを学ぶリファクタリング リファクタリングには良い学びがある。間違いを認識し、良いプラクティスを積み上げよう。 学び これまでのまとめなので、特になし 学びを活かすアイディア・行動 現場メンバーへの展開

レガシーコードからの脱却 まとめ – 13.6 – 13.8

13.6 オープン・クローズドにリファクタリングする 内容 SOLID原則のOこと、オープン・クローズドの原則では、ソフトウェアは「拡張に対して開かれているが変更に対して閉じられている」べきだとしている。こうすると、新しい機能の追加は、新しいコードの追加と最小限の既存コード変更で済むようにする。 変更を加える際は常に2段階のプロセスで進める。 まず新しい機能に対応できるように、拡張したいコードをリファクタリングする。この時点ではまだ新しい機能は追加しない。リファクタリング中の間違いはテストが教えてくれる。 次に機能拡張ステップに入り、テストファーストでレッド・グリーン・リファクタリングを繰り返す。 この手順を混同して進めると混乱して間違えやすい。 13.7 リファクタリングで変更しやすさを確保する コードの変更しやすさを担保することは、正しい抽象化を見つけ、コードが適切にカプセル化されていることを意味する。 つまり、正しい抽象化とはなにかを理解し、それを見つけていき、カプセル化を理解し、カプセル化をしていくことが重要だ。 最終的に重要なのは「自分がモデル化しているものを理解してモデルへ組み込む」ことで、これが正確性と一貫性をもたらす。 プラクティスやTDDは、自分がやろうとしていることを明確にするためのサポートはしてくれるが、自分がやろうとしてくれることそのものをすべて生み出してくれるわけではない。 コードの変更しやすさが偶然生まれることはない。 13.8 2回めは適切にやる 正しい抽象化は、複数のふるまい・具体的な例を挙げることで、何が同じで何が違うかが浮かび上がり、そこから汎化することで見つけられる。 この作業は、具体例が多いほど精度が高くなり少なければ精度が低くなる可能性があることを意味する。プロジェクトが進むにつれて、具体例は見えてくる傾向にある。つまり、プロジェクト初期は精度の高い適切な設計が難しいことを意味している。 ソフトウェアの「柔らかい」特性を理解して、いつでもリファクタリングできるようにしておくことで、プロジェクトを進めながら設計の精度を上げることができる。 学び 修正する際はオープン・クローズドの原則を意識すること 修正は、拡張用のリファクタリング→機能追加の2段階プロセスを踏む。そのためには、どのように拡張するかをドラフト設計する。 プロジェクトを進めながら、リファクタリングしながら設計の精度をあげよう。 学びを活かすアイディア・行動 現場にプラクティスを展開する モデル化の学習 カプセル化の学習 正しい抽象化、カプセル化を理解することが重要 TDD実践記の展開

レガシーコードからの脱却 まとめ – 13.4 – 13.5

13.4 リファクタリングのテクニック 13.5 変化に対応するためのリファクタリング 内容 リファクタリングのテクニックを紹介するよ。 リファクタリングの手法はたくさんあるが、目的は顧客が変更したいものを変更しやすくすることだ。 それを前提に、標準的なやり方を示す規律を作り、直感的に行うのではなく、皆が共通認識を持ち安全に繰り返していくことが望ましい。 13.4.1 ピンニングテスト DIできるようになるまで(モジュールが分離できるようになるまで)、粒度の粗いテストを書いてコード変更できる準備をする。そしてコードをリファクタリングしてテストを再実行しながら少しずつ修正する。DIできるようになると、モックを使うことができるようになるので、モジュール単位で細かいユニットテストができるようになる。 13.4.2 依存性の注入 DIはモジュールを切り離すことができる。そしてモックを注入すればテストができ、モジュールの正しさは担保できる。そして切り離されていることで、そのモジュールに集中してテスト、リファクタリングができる。 13.4.3 ストラングラーパターン システムを停止せずにコンポーネントを変更する場合は、ストラングラーパターンを使う。古いサービスをラッピングする形で新しいサービスを作り、最終的に古いサービスがなくなるまでゆっくりと置き換えていくという考え方である。 リファクタリングに使える手法だ。 13.4.4 抽象化によるブランチ 「抽象化によるブランチ」は変更したいコードからインターフェイスを抽出して、新しい実装を書くというものだ。そして開発中はフラグで古い機能が動くように管理しておき、新しい実装ができたらフラグで新しい機能が動くように切り替える。 学び DIできる状態かどうかは重要な指標。まず粒度の粗いテストでそこを目指すとよい。 モジュールの種類別に役割を概ね決めておいて、リファクタリングの目標の像をある程度明確にする必要がある。 DIはリファクタリングの手助けをする。 アプリ配信の場合、どのように適用できるだろうか。 抽象化によるブランチというテクニックはフラグのスイッチングを前提に小さなリリースをしていくことに向いている。 リファクタリングの目的はソフトウェアが変更可能でありつづけることで、それを忘れてはいけない。 リファクタリングの手法は体系的で共通認識を持っていることが望ましい。 学びを活かすアイディア・行動 ピンニングテストが必要な箇所の洗い出し DIすべきポイントの洗い出し ストラングラーパターンを使ったリファクタリングの適用の検討 抽象化によるブランチを適用したら効果的にリファクタリングできる箇所がないか調査 毎日学習した内容の展開をする

レガシーコードからの脱却 まとめ – 13

13 プラクティス9 レガシーコードをリファクタリングする 内容 リファクタリングとは、外部へのふるまいを変更せずに、コードを再構築または再パッケージ化すること。 リファクタリングすることをマネージャーに伝えるときは、リファクタリングがビジネスにとってどう価値があるかを伝える必要がある。 リファクタリングは以下4つのコストを削減する。 あとからコードを理解する ユニットテストの追加 新しい機能の追加 さらにリファクタリングをする 納期を守るために、ときに雑な仕事をしてしまったものも出てくるだろう。そういうものはリファクタリングで修正する。 学び リファクタリングは、理解容易性、変更容易性を上げることができる。 コストを減らす観点で言うと以下のようになる。マネージャーと会話するため。 あとからコードを理解する。つまり、メンバー変更や担当変更がしやすくなる。 ユニットテストの追加。リファクタリングがさらに行いやすくなる。 新しい機能の追加。コードが整理されるので、拡張性を上げることができる。 どのリファクタリングをいつやるかという話をするときに、マネージャーと会話するための語彙が必要。 学びを活かすアイディア・行動 リファクタリングを実際にいつやるかのマネージャーとの会話

レガシーコードからの脱却 まとめ – 12.3 – 12.4

12.3 コーディング対クリーニング 内容 コーディング・・・特定のタスクの解決方法を探す作業。テストを通すことに集中する。 クリーニング・・・動くコードを保守可能にする作業。扱いやすくすることに集中する。 それぞれ、別のタスクとして捉えて進めたほうが効率が良い。 技術的負債は短期的にも長期的にも返済を続ること。短期的には、テストファースト開発のリファクタリングステップにて。長期的には、チームの学習をコードに取り込むための定期的なリファクタリング作業の中で。 それでも技術的負債が溜まり続けてしまう場合もある。新しい機能を実装するために設計変更が必要だったり、単にもっと良いやり方を思いついたりする場合だ。その場合、通常数か月ごとに、大規模なリファクタリングを行い、技術的負債の返済作業を行う。この場合でも、ユニットテストが助けとなる。 12.4 ソフトウェアは書かれる回数より読まれる回数のほうが多い 平均してコードは書かれる回数の10倍読まれる。効率性、拡張性のために読みやすくなければならない。コードは自分のためではなく読み手のために書け。 コメントの注意点1わかりやすくするためにコメントを書くことがある。注意点として、コードが「そうなっている理由」を書くのは良いが、「やっていること」を書くのは良くない。「やっていること」はコードで表すべきだ。まず、冗長である。そしてコメントの運用の手間が二重になり、コメントの修正漏れによりコードとの差分が生まれる可能性が発生する。どちらが本来正しいのかがわからなくなる。 コメントの注意点2「わかりにくい理由」を書く前に、一度わかりやすく出来ないか設計を考えよう。 学び 技術的負債のタイミングは、以下3つ。 テストファースト開発のりファクタリングステップ、 チームの学習をコードに取り込む定期的なリファクタリング、 それでも溜まってしまう技術的負債を解消するための大規模なりファクタリング コードは平均して、書かれる回数の10倍読まれる。読めるように書こう。 学びを活かすアイディア・行動 大規模なリファクタリング計画と実施 現場のコーディング規約づくり

レガシーコードからの脱却 まとめ – 12, 12.8

12章 プラクティス8 設計は最後に行う 内容 ソフトウェア開発では、保守性の設計は最後にしたほうが良い傾向がある。プロジェクトの終盤の方が、システムの全体に対して理解が深くなっており、適用させるデザインパターンの判断もしやすくなる。実現の手段として、ユニットテストのサポートを受けながら、再設計とリファクタリングを行う。 反復開発は設計を創発する。創発とは、最初の設計よりも開発が進むに連れ、もっと良い設計が見えてくることを指す。 12.8 創発する設計 原則として、テストファースト開発を行いながら、理解容易性、テスト容易性に注意を配りながら開発していけば、修正しやすいプログラムになり、あとから生まれた設計を取り込むことも、テストがサポートしてくれる。 創発した設計を取り込むことができないということは、修正がしづらいことを意味し、それを続けているといずれ保守可能でないシステムになり、システムはビジネスの拡張についていけなくなるし、エンジニアたちも苦しむことになる。 学び 保守性を加味した設計とリファクタリングは、テストが書かれている前提であれば、プロダクトの全体像が見えるプロジェクトの後半が適している。 テストファースト開発は創発した設計を取り込むことができる。 最初に設計しきるのは現実的ではない。だから、創発した設計を取り込めるプロセスを作ることが重要だ。 学びを活かすアイディア・行動 まずは実践し、メンバーに手法として展開する テストコードの目的の事前知識整理