長すぎるメソッド
新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)を引き続き読んでます。
新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)
- 作者: Martin Fowler,児玉公信,友野晶夫,平澤章,梅澤真史
- 出版社/メーカー: オーム社
- 発売日: 2014/07/26
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (11件) を見る
長すぎるメソッドにどう対応すべきか、という「メソッドの構成」の章をメモる。
メソッドの抽出
ひとまとめにできるコードの断片がある場合、そのまとまりをメソッドに切り出す。
作成したメソッドには、目的を表す名前をつける。
メソッドのインライン化
メソッドの本体が名前をつけて呼ぶわけでもなく明らかな場合、インライン化してメソッドを除去する。
一時変数のインライン化
簡単な式によって一度だけ代入される一時変数があり、それが他のリファクタリングの障害となっている。
その一時変数への参照を全て式に置き換える。
問い合わせによる一時変数の置き換え
一時変数はメソッド内でしか参照できない。一時変数を使うためにはそのメソッドにロジックを書くしかないため、長いメソッドの誘因となる。
一時変数を別メソッドに置き換えれば、どのメソッドでも使えるようになりクラスのコードは整理しやすくなったりもする。
<?php $pointNum = $basePoint * $num; if($pointNum >= 500){ return self::MAX_POINT_NUM; }else{ return $pointNum; }
↓
<?php // $basePoint * $num をメソッドの抽出する // 一時変数の参照を新たなメソッドに置き換える if(getPoint($num)>= 500){ return self::MAX_POINT_NUM; }else{ return getPoint($num); } function getPoint($num){ return $basePoint * $num; }
説明用変数の導入
式は、ときに極めて複雑で読みにくくなることがある。
そんなときに、一時変数を使って式を分解して扱いやすくする。
<?php if ((strpos($ua, 'Android') !== false) && (strpos($ua, 'iPhone') !== false)) { // 略 }
↓
<?php $isAndroid = strpos($ua, 'Android') !=== false ? true : false; $isIphone = strpos($ua, 'iPhone') !=== false ? true : false; if ($isAndroid && $isIphone) { // 略 }
一時変数の分離
何回も代入される一時変数があるが、ループ変数でも一時変数を集める変数でもない場合、代入ごとに別の変数を使うようにする。
パラメータへの代入の除去
パラメータへの代入が行われていると、「値渡し」と「参照渡し」の間の混乱が起きる。
一時変数を使って切り分ける。
<?php function getPlan($day, $time){ if($time >= 2400){ $day = $day + 1; $time = $time - 2400; } }
↓
<?php function getPlan($day, $time){ $planDay = $day; $planTime = $time; if($time >= 2400){ $planDay = $planDay + 1; $planTime = $planTime - 2400; } }
メソッドオブジェクトによるメソッドの置き換え
長いメソッドで、メソッドの抽出が適用できないようなローカル変数の使い方をしている。
メソッド自身をオブジェクトとして切り出し、すべてのローカル変数をそのオブジェクトのフィールドとする。そうすれば、そのメソッドを同じオブジェクト中のメソッド群に分解できる。
アルゴリズムの置き換え
メソッドの本体を新たなアルゴリズムに置き換える。
置き換え前には、必ずできるだけメソッドを分解しておくこと。大きく複雑なアルゴリズムを置き換えることは困難である。
「コードの不吉な臭い」もタメになった
同本の「コードの不吉な臭い」もとてもタメになった。前にこちらでまとめましたので、よければ参考までに。 blog.darudaru-life.com