注: 記述する上で面倒なので、以下で「関数」と単に書いてある場合、メソッドやプロシージャといったものをまとめて指すこととする。

TL;DR

「分割」しようとするな。一つ一つ、別の処理に「分解」しろ。

そもそもなぜ「分割」しろといわれるのか

短くしたいから

人間、長い文章は途中で混乱するものだ。
そしてプログラムも結局は文章である。

多くの日本人が英語の本を読んだら混乱するように、人類は長いプログラムを読むと混乱する。これは当然だ。

なにしろプログラムは「プログラミング言語」という言語で記述されている。この言語は困ったことに、なんと外国人どころかコンピュータと対話するための言語である。
そりゃあ、慣れないうちは(あるいは慣れたとしても)混乱して当然だ。

重要なのは「短い」ことではない

「This is a pen」は日本人を混乱させるだろうか。
もちろん、させないだろう。「これはペンです」。簡単だ。

では「Er ist wieder da」はどうだろう (いや、これは人によっては通じると思うが) 。
答えは「彼、再び」といった具合になるらしい。ちなみにドイツ語で、小説のタイトルである。彼再び!って、なんのこっちゃ?1

そう、仮に十分に短い場合であっても、それ単独で意味が通じなければ、結局多方面を調べ回るハメになる。当然時間がかかる。
重要なのは、わかりやすいことだ。もし混乱しないのであれば、長くてもその方がよい。
短くしろと言われるのは、短ければ「マシ」になりやすいからであって、短くすることそれ自体は解決策たり得ない

ここにクソ長いメソッドがあり、これを短くしろと命じられたとする。

public void hoge(List<Hoge> h, List<Fuga> f){

    ...(なんかいっぱい)...

}

駄目な例

「切り離しました!」

public void hoge(List<Hoge> h, List<Fuga> f){

    part1(h, f);
    part2(h, f);
    part3(h, f);

}

private void part1(List<Hoge> h, List<Fuga> f){

    ...(なんか)...

}

(以下略)

ぶん殴られても文句言えない

何が駄目か

単純に、結果どうなるのかを見通すためには全部読まなければならない
part1, part2, part3 はそれぞれ独立していないので、本当にただ切り離しただけなのだ。
こうなってくると単に連続した処理が別の場所に書かれただけで、いろいろなところを読まなければならない分却ってめんどくさい

どうすべきか

こうすると少し改善する。
(他にもいろいろやるべきことはあるが、今回の記事でいいたいのはここ)

public void hoge(List<Hoge> h, List<Fuga> f){

    List<Pair<Hoge, Fuga>> result1 = part1(h, f);
    List<Pair<Hoge, Fuga>> result2 = part2(result1);
    List<Pair<Hoge, Fuga>> result3 = part3(result2);

}

protected List<Pair<Hoge, Fuga>> part1(List<Hoge> h, List<Fuga> f){

    ...(なんか)...

}
protected List<Pair<Hoge, Fuga>> part2(List<Pair<Hoge, Fuga>> result1){

    ...(なんか)...

}

(以下略)

どう違うのか

先ほどと違い、part1, part2, part3 はそれぞれ「結果」を返している
乱暴な言い方だが、結果が出るということは、その処理一つだけでも意味が通り、検証が可能だということである
このため、自動ユニットテストも掛けやすくなる。手動のテストもいくらかやりやすくなるだろう。
(protected になっていることに気づいたらなかなか鋭い。普段ならリフレクションで private を触らせるが、今回はそういう意味合いも込めて protected にした)


  1. 結構面白かった。日本語訳も出てるので興味があれば調べるとよい。そう、調べないとわからんだろ。 

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.