<< 複雑さと戦う : データの入れ物 テーブル  | main | 複雑さと戦う : オブジェクトの海を整理する >>

複雑さと戦う : 手続きに注目したリファクタリング

ドメイン(問題領域)の知識が増えてくるとソフトウェアが複雑になる。
ビジネスルールを記述するため、if 文が増え、区分コードや状態フラグが増え、ひとつのメソッドに延々とコードがならぶ。 

・メソッド内でインデント(段付け)が必要になる
・3行以上、空白行や {} の区切りがないコードが続く
・ && や || を使う

私のルールでは全部アンチパターンです。

void method()
{
input();
doSomething();
output();
}

このくらいがメソッドとしてちょうど良い感じ。これ以上複雑なメソッドは、リファクタリング(設計の改良)の候補です。

ファウラーの「リファクタリング」で、複雑になりはじめたコードを改良するパターンをいろいろ説明している。

メッソッドの抽出

コードをひとまとめにして、別のメソッドとして抽出する。
そのひとかたまりに名前(メソッド名)をつける。

データが並んだときと同じで、コードがならんだら、意味のある区切りに空白行を挿入する。 そのかたまりを別メソッドにする。

本の例では、2行の System.out.println() 文を まとめて printDetails() メソッドに抽出しています。

条件記述の分解

(リファクタリング前)

if( date.before(SUMMER_START) || date.after(SUMMER_END) )
{
charge = qauntity * _winterRate + _winterServiceCharge ;
}
else
{
charge = quantity * _summerRate ;
}

リファクタリング後

if( isSummer( date ) )
charge = summerCharge( quantity ) ;
else
charge = winterCharge( quantity ) ;

boolean isSummer( Date date ) { ; }
dobule summerCharge( int quantity ) { ; }
dobule winterCharge( int quantity ) { ; }

というように、評価式、計算式をそれぞれ別メッソドとして抽出する。 コードの意味がわかりやすくなったでしょう。
適切なメソッド名を使えば、コメント文での説明も不要。

ガード節で if-else の入れ子を置き換える

if( 条件A )
else
{
if( 条件B )
else
{
if( 条件C )
else
{
return normalResult ;
}
}
}
というようなコードを、

if( 条件A ) return getA() ;
if( 条件B ) return getB() ;
if( 条件C ) return getC() ;

return normalResult ;

というように return 文を使って、 else 文を無くす。
複雑な条件文が見違えるほど、わかりやすくなりますね。

メソッド名の変更

getinvcdtlmt()

getInvoiceableCreditLimit()

ロジックをたくさんの小さなメソッドに分割した時、メソッドの名前をわかりやすくすることが大切。
わかりやすいメソッド名はそれだけで、メソッドの内容を説明する。コメントの補足は不要です。

問合せと更新の分離

Object getSomethingAndSetAnotherThing()

Object getSomething();
void setSomething();

get と set を同時に行っているメソッドを見つけたら、とにかく分解しましょう。

改良した設計のコードはこんな感じになる。
・どのメソッドも短い (3行くらい)
・メソッドの名前がわかりやすい (名前は長め)
・if 文のネストが消える
・else 文が消える

あと、コレクションフレームワークやアプリケーションフレームワークを使えば、for 文も激減します。

for 文や if 文を駆使するより、 もっとシンプルに書きましょう。
そのほうが、読みやすく、安心して変更できるソフトウェアになりますね。

コメント
コメントする









この記事のトラックバックURL
トラックバック
calendar
  12345
6789101112
13141516171819
20212223242526
27282930   
<< September 2020 >>
システム設計日記を検索
プロフィール
リンク
システム開発日記(実装編)
有限会社 システム設計
twitter @masuda220
selected entries
recent comment
recent trackback
categories
archives
others
mobile
qrcode
powered
無料ブログ作成サービス JUGEM