新装版リファクタリング感想(第1章だけ)

印象に残った部分のメモを残します。

第1章 リファクタリングー最初の例

メソッドの抽出

page 9より引用

最初に、抜き出そうとする部分でローカルなスコープをもつ変数に着目し、それらが新規に作られるメソッドの一時変数かパラメータにならないか検討します。

ここまで言語かできてないし、全く同じことではないけど似たようなことはやってる!と思った。

条件によって代入する値が変わる場合にswitch文の中でそれをやるコードを良く見る。
しかし、スコープが比較的広く、再代入が可能なローカル変数は値が再代入されるのかを気にしなければならない。
それが嫌なため、該当処理をprivateメソッドや別クラスに括りだすようなことをよくやる。

自分が実践しているテクニックと似たようなものが紹介されていて少しテンションがあがった。

問い合わせによる一時変数の置き換え

page 21より引用

そこで、「問い合わせによる一時変数の置き換え」を適用することにします。

私はいままではオブジェクトから値を取り出すときはパフォーマンスを考慮して一時変数を利用していた。
しかしこの本によるとメソッドから取り出すことがパフォーマンスに影響することをリファクタリング時には気にしすぎなくて良いらしい。
さらには

しかし実際には、コードは適切に分割することで、もっと効率よく最適化できるのです。

とのこと。

実際のコード例はこんな感じ。

Before

            double thisAmount = 0;
            Rental each = (Rental) rentals.nextElement();

            thisAmount = each.getCharge();

            // レンタルポイントを加算
            frequentRenterPoints++;
            // 新作を2日以上借りた場合はボーナスポイント
            if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDaysRented() > 1)
                frequentRenterPoints++;

            // この貸出に関する数値の表示
            result += "\t" + each.getMovie().getTitle() + "\t" + String.valueOf(thisAmount) + "\t" + "\n";
            totalAmount += thisAmount;

After

            Rental each = (Rental) rentals.nextElement();

            // レンタルポイントを加算
            frequentRenterPoints++;
            // 新作を2日以上借りた場合はボーナスポイント
            if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) && each.getDaysRented() > 1)
                frequentRenterPoints++;

            // この貸出に関する数値の表示
            result += "\t" + each.getMovie().getTitle() + "\t" + String.valueOf(each.getCharge()) + "\t" + "\n";
            totalAmount += each.getCharge();

本当に問題にならないかについては業務で試してみようと思う。
パフォーマンステストをちゃんとやる前提で。

まとめ

第1章の内容はテスト駆動開発の第1部多国籍通貨のようにペアプロをしているように感じさせる書き方だった。
ただ、テストコードがないため自分で書いたものを使った。

後半で「ポリモーフィズムによる条件記述の置き換え」の例が出ていた。 私もswitch文が登場したら不吉な匂いを感じて多くの場合は書き換えるのだが、それをほかの人に説明するための具体例に困っていた。
今後はこの書籍の例を引用したいと思う。

私は手続き型で書かれたコードをリファクタリングする際にこのテクニックは頻出だと思っているが、自分の経験の中には「誰にでも」しっくり来る例がなかったので良い例を知れたことが嬉しい。1

年齢の割にプログラミング歴が浅い&詳しい業務が偏っている私にとって、書籍から得られる汎化された知識・テクニックはとても有り難い。

全編を通して読んだが、(直前で言ってることとは矛盾するが)経験を積んだおかげか大部分を理解できた(と思う)。
だいぶ前に増補改訂版Java言語で学ぶデザインパターン入門を読了済みだったため、予備知識があったからだと思われる。

DDD本と同じく2〜3回再読してしっかりを知識を染み込ませよう。

ちなみに、今まで我流で身につけた方法にこの本の手順を組み入れたやり方2を既に現場で実践し始めた。

以上。


  1. 私は一番長く関わっている業務分野が認証なのだが、この文脈の中から例を取り出してもわかってもらえることが少ない

  2. 組み入れたと言ってみたが、大部分はほんのやり方に置き換わった