関数の適切な長さとは? マーチン・ファウラー氏は、長さより意図と実装の分離、そしてよい関数名が重要だと指摘
一般にプログラムは多くの関数などから構成されています。関数には数百行に渡る長いものから数行程度の短いものまでさまざまな長さがありますが、果たして関数にとって適切な長さというのはあるのでしょうか?
マーチン・ファウラー氏は関数の長さについて書いたコラムで、重要なのは意図と実装の分離であり、適切な名前を付けることが大事だと指摘します。同氏のブログは翻訳が許可されているので、記事「FunctionLength」の本文を翻訳しました。
FunctionLength(関数の長さ)
私のキャリアにおいて、関数の長さはどれくらいであるべきか、という議論を何度も聞いてきた。これはより重要な問いに置き換えることができる。それは、どのくらいの長さのコードになったらそれを関数にすべきか、ということだ。
いくつかのガイドラインでは、1画面におさまらなくなったら、とあるし[1]、それ以外にも再利用するかどうかを基本に、二度以上繰り返す処理であれば関数にすべきであり、そうでなければそのままインラインにしておく、というのもある。
しかし私にとってもっとも理にかなっていると思われたのは、意図と実装の分離というものだ。もしも、なにをしているのか理解するのに努力しなければならないコードの一部分があったとしたら、そこを関数として切り出し、“what”に続いてそのその「なに」にちなんだ名前を付けてしまうのである。
こうすれば、もう一度そのコードを読んだときに、そのコードの目的はすぐさま目に飛び込んでくるだろうし、その関数がやろうとしていること、すなわち関数本体に注意を払う必要はなくなるだろう。
私はこの規律を採用してから短い関数を書くようなった、典型的には数行だ[2]。コードが6行を超えると、もう私にとっては関数の匂いを感じ始めるし、1行のコードからなる関数でさえ珍しくない[3]。
実のところコードのサイズが重要なのではない、という考えは、ケント・ベックがオリジナルのSmalltalkシステムにおける実例によって示してくれたものだった。当時のSmalltalkはモノクロディスプレイで動作していたので、テキストやグラフィックをハイライト表示したいときには、画像を反転させることで実現する。そしてSmalltalkの画像のクラスにはこの“Highlight”(ハイライト)と呼ばれるメソッドがあり、この実装は単に“reverse”メソッドを呼び出すものだったのだ[4]。
この名称は実装よりも長いのたが、コードの意図とコードの実装のあいだには大きな距離があったから、そのことは大きな問題にならなかった。
関数の呼び出しコストによる性能劣化を気にして短い関数に懸念を示す人もいる。私がまだ若かった頃はしばしばそうした要素もあったけれど、現在ではほとんどないだろう。最適化されたコンパイラであれば短い関数はキャッシュしやすいため、より適切に扱えるようにもなっている。
とはいえ、これまでと同様、性能の最適化に関する一般的なガイドラインは重要だ。ときには、関数をあとからインラインに変換することが必要になることもあるだろう。一方で、小さな関数は性能向上に向けたほかの選択肢をしばしば教えてくれる。
私は、一般的な慣用句としてリストのメソッドにaList.length == 0を使用し、isEmptyメソッドの使用には反対する人たちを見たことがある。しかし関数の意図を明確に示した関数名を使用すれば、コレクションが空であることを判定する方が長さを判定するよりも高速ならば、それをサポートすることもできるようになる。
このように小さな関数は名前が良い場合にのみ機能するので、名前付けには注意を払う必要がある。 これには練習が必要だけれど、ひとたび上達したならばこの方法でコードを高度に自己文書化できる。より大きいスケールで見れば、関数は物語のように読むことができ、読むものにとって必要なときにどの関数を詳しく読み込んでいくか選択できるようになるのだ。
あわせて読みたい
NTT、ネットワーク障害の原因を推定するAI技術を開発。従来のネットワークエンジニアによる分析と切り分けを不要に
≪前の記事
Google、書籍「Site Reliability Engineering」の無料公開を開始。インフラや運用をソフトウェアで改善していく新しいアプローチ