勉強日記

チラ裏

Refactoring ch2 Principles in Refactoring (1/2)

martinfowler.com


Defining Refactoring

If someone says their code was broken for a couple of days while they are refactoring,
you can be pretty sure they were not refactoring.

  • 昨今「リファクタリング」という言葉が緩く使われるが、著者による定義はこう
    • 名詞
      • ソフトウェアの、外から観測可能な振る舞いを変えることのない、内部構造の変更
        • わかりやすく
        • 変更コストが低くなるよう
    • 動詞
      • 一連のリファクタリング(名詞)を適用し、外から観測可能な振る舞いを変えずにソフトウェアを再構築すること
  • リファクタリングする(動詞)のに数時間費やすことはありうる
  • 「再構築」(restructuring)の特別なヤツという位置づけ
    • 壊れた = 振る舞いが変わってしまった状態が長く続くようなら、それは「リファクタリング」ではなく単なる再構築
  • 「外から観測可能な振る舞いを変えない」って何
    • 機能を変えないということ
    • 非機能 -- コールスタックとかは変わる
      • パフォーマンス特性は変わることがある
  • パフォーマンスチューニングとは似て非なるもの
    • 共通点: 機能を変えない
    • 相違点: 目的
      • リファクタリング: 開発コスト下げる
        • パフォーマンスは犠牲になることがある
          • パフォーマンスチューニングはしやすくなる
      • パフォーマンスチューニング: 実行時パフォーマンス上げる
        • 可読性等は犠牲になることがある

The Two Hats

  • 機能開発・リファクタリングを交互に切り替えて開発を進めていくことを、帽子をつけかえることに例える

Why Should We Refactor?

Refactoring Improves the Design of Software

  • 一度設計したきり、継ぎ足し継ぎ足しで開発をすすめると、アーキテクチャは加速度的に腐っていく
    • 完全に理解せずに継ぎ足すため、既存のコードの構造を損なう
      • 重複コードを追加してしまったりする
    • コードの構造を損なうから読みづらくなる
    • 読みづらいので完全に理解できなくなる
  • リファクタリングはこれに逆行する営み
    • 重複をなくす
      • 理解しなければならない対象を減らす

Refactoring Makes Software Easier to Understand

  • 他人にも自分にも読みやすいコードに
  • いちいち覚えていたくないため、読めばわかるようにしたい
    • 長い時間かけて読解した内容をコードにフィードバックする
    • 次回からは短い時間で読める

Refactoring Helps Me Find Bugs

I'm not a great programmer; I'm just a good programmer with great habits. (Kent Beck)

  • 著者はバグを見つけるのが苦手
  • リファクタリングを行うと、コードが明確になり、嫌でもバグが見つかるようになる

Refactoring Helps Me Program Faster

  • そもそもの目的
  • 短期的には遅くなるが、長期的に見てペイする
    • 機能の追加時、どこを触ればいいかわかりやすい
    • コードが明確なのでバグが入り込みづらい
    • デバッグ工数減る
  • Design Stamina Hypothesis
    • 良い設計(内部構造)は、新機能追加のスタミナになるよ、という仮説
    • 最初に良い設計を行うのは難しい
    • 設計を向上させるためにリファクタリング
      • 【補】本の副題にもなっている
        • Improving the Design of Existing Code

When Should We Refactor?

The Rule of Three

  • 最初は単にやる
  • 次に似たことをする時が来たら、しかめ面をしつつやる
  • 三度目が来たらリファクタリングする

(Don Roberts)

Preparatory Refactoring -- Making It Easier to Add a Feature

まっすぐ森を突っ切るよりも、3倍の速さで迂回するほうが早い

  • これからする作業が楽になるように、下準備としてリファクタリングする
    • 新機能追加
    • 不具合修正

Comprehension Refactoring: Making Code Easier to Understand

  • 既存のコードを改変する間に、まず「それが何をしているか」理解する必要がある
    • 過去の自分が書いたコード
    • 他の誰かが書いたコード
  • 見てすぐわかるようにリファクタリング
    • 変数の名付けの改善
    • 長い関数の分割
  • 脳内の理解をコード自体に移す (Ward Cunningham)
    • 長く残る
    • 同僚にも見えるようになる
  • 将来の為ならず、今も役に立つ
    • ノイズが減り、見過ごしていたことに来づけるようになる

Litter-Pickup Refactoring

  • ボーイスカウト・ルール定期
  • Comprehension Refactoringのバリエーション
    • コードが何をしているかわかったが、やり方がうまくない
      • 無駄に込み入っている
      • ほとんど同じで、パラメータ1つの関数に置換できる関数たち
    • 楽勝ならその場で直す
    • 何時間かかかってしまいそうならメモだけして後回し
      • やる価値はある

Planned and Opportunistic Refactoring

You have to refactor when you run into ugly code
-- but excellent code needs plenty of refactoring too.

for each desired change, make the change easy (warning: this may be hard), then make the easy change.
Kent Beck

  • ソフトウェアは「完成」ということはない
    • 機能追加前提で、追加しやすく作れ
  • リファクタリングと機能追加のコミットは分けろ」と聞く
    • 主な理由は「別々にレビュー・承認を受けられることから」
    • 著者はこれにしっくり来ていない
    • 「そのほうが仕事をしやすい」ならば価値がある

Long-Term Refactoring

  • 何週間もかかるようなケース
    • ライブラリの置き換えとか
  • リファクタリングのためだめの時間をまとまって取ることは難しい
  • 通常の開発の中で、ちょっとずつ理想形に寄せていくとよい

英語

  • altruistic
    • 利他的
  • maudite
  • archaeology
    • 考古学
  • slate
    • スレート
    • 粘板岩
      • 地層を構成するやつ
  • wince
    • たじろぐ
    • 顔をしかめる
  • traipse
    • (山野を)うろつく
  • forego
    • 先んずる、予見する
  • accretion
    • 小さい物質粒子が重力相互作用でくっつき合うこと
  • (shudder)
    • (震え)
  • amenable
    • 従順な
  • nine times out of ten
    • 十中八九
  • onward
    • 前進的な
  • accrue
    • 生じる
  • compelling
    • 人の心をつかんで離さない、賞賛せずにいられない、非常におもしろい
      • 文中では、IDEの有能な機能に対して言っている
  • gaily
    • 陽気に
  • go pear-shaped
    • 駄目になる
      • 円を描こうとしていびつな形になってしまう様子から