関数の作り方
目次
関数がうまく作れない?
なんかいまいちピンとこない関数をつくってしまう。
関数の名前も微妙。たまに内容と乖離した関数名をつけてしまう。
などなど。
このようなエンジニアを初めて日が浅い方向けの内容になります。
この記事でいいたいこと
- 目的・機能を関数名にする
- 再利用性がない関数もあり
- リファクタリングで関数を作る時は適度に長いコードに注目
関数のある意味
プログラムを初めてすぐは関数を作るのが難しいです。
関数を作る時に考えることはなんでしょう。
- テストを容易にする
- 再利用をして無駄を減らす
実際私が昔考えていた関数の用途でもありまが
しかし今は別で大事なことがあると考えています。
関数は英語ではfunctionといいますね。
関数 = function = 「機能, 作用」
つまりは関数とは「何かをする」機能です。
さらにいうと関数とは目的となる機能とその手段が書かれているものです。
しかし「テストを容易にする」とか「再利用して無駄をへらす」とも
よく言われるのも事実です。
関数のメリットとしてこれらがあると認識していますが、
関数の本来の用途、といわれると違うと考えています。
では、それぞれ違うと考える理由を提示します。
テストが関数のためにある
エンジニアがテストを容易にするに向かうことは生産性の観点で大事な要素です。
しかし、テストをする理由とはなんでしょう。
関数が正しく動くかをテストして確かめることです。
関数をテストを容易にするために作るという観点では
関数とテストの立場が逆転してしまっています。
ですので「テストを容易にする」はとても大切ですが
関数を作る用途としては間違いと考えています。
再利用をして無駄を減らすことよりも大切なこと
手元にコードがあるならば一か所でしか呼ばれていない関数を
探してみてください。
それは一か所でしか使われなくても立派な機能として
使用されていると思います。
世に出ているサービスでも再利用されていない機能はあります。
例えば物販(EC)サイトで「重要なお知らせ」を表示する関数
について考えます。
それは商品一覧できるページに使われたり、注文直前に使われたりします。
複数の箇所で使われるので再利用もされます。
では「重要なお知らせ」新規作成する関数はどうでしょう。
おそらく重要なお知らせ作成画面から使用されますが、
しかし、作成画面以外で再利用性されない可能性が高いです。
つまり再利用性が不要な関数があってよいということです。
ですので再利用前提でつくるのが難しいならば、
再利用については最初考えないのもありです。
再利用性は、関数(機能)を作るの一歩先の考え方なのですが
それは、たくさん「機能」があるから保守しやすくしようということです。
関数を作ることに慣れていない状態で保守性を考えて余裕がなくなると
足元の「機能」が揺らいでしまい名状しがたい関数になることも。
たぶん関数名を付けるのに苦労します。
再利用性にこだわるあまりプロパティをセットしているだけの関数、
「前処理()」みたいな名前になっている場合は要注意です(自戒)
関数を作る時は目的と手段を意識しよう
繰り返しになりますが、関数とは目的とその手段が書かれているものです。
関数名が目的、関数の処理内容が手段です。
では例を交えて深堀します。
物販(EC)サイトのプログラムで注文するとき、
- 「在庫を押さえる」
- 「決済する」
- 「注文者情報を登録する」
このようなことをしていると思います。
まずダメな例からです。
関数名がを表現するとこんな感じです。
データを登録する()
{
クエリを作る;//在庫を押さえるクエリ
クエリを発行する;
カード会社のAPIと通信をする;
クエリを作る’;//注文者情報を保存するクエリ
クエリを発行する;
}
目的、と手段にフォーカスしてみます。

目的が「データを登録する」になっていますが、「何の?」と疑問がわきます。
「物販(EC)サイトのプログラムで注文する」が本来の目的なのですから
関数名も「注文する」にしてあげるとしっくりきます。

これで「データを登録する()」よりも何を目的にしている機能かが
わかりやすくなりました。
次は「注文する」関数をさらにわかりやすくしていきたいと思います。
注文するが
- 「在庫を押さえる」
- 「決済する」
- 「注文者情報を登録する」
で構成されているならばその名の関数(機能)を作ってあげます。

このように目的となる機能ごとに分けてあげると
呼び出し元がさらにわかりやすいコードになります。

自分が書こうとしている関数が何に使われているかを考えるのはとても重要です。
さらに意味の伝わる関数とコードにするには関数名をつけるとき
その関数がどのように利用されるかを考えてあげるよいです。
既存のプログラムから新しく関数をつくる
あまり関数を作ったことがない方ならば
既存のプログラムをリファクタリングして作るのがお勧めです。
- 100行~1000行くらいのコード
- if文for文が多いコード
で探すとよいと思います。
100行以下のコードですとすでに最適化されている関数の公算が高く
新しく関数を作るのは難しいです。
逆にまた1000行を超えてくると全体把握が大変なので
その間の100~1000行で探すとよいと思います。
次にif文for文が多いところに機能が隠れている可能性があります。
複雑な条件分岐の時は判定機能になりやすく効果的。
if()
{
}
else
{
if()
{
if()
{
//ここに大量のコード
}
}
}
もしこのif文が「販売してよい」を表現しているなら関数化します。
bool isSaleable(object[] args)
{
if()
{
}
else
{
if()
{
if()
{
return true;
}
}
}
}
そうすると呼び出す元がすっきりして可読性もあがります。
if (isSaleable(args))
{
//大量のコード
}
まとめ
関数を作る時様々な要素が絡んできます。
テストは?
再利用性?
メモリ消費?
.etc
全部重要です。
ですがいったんはシンプルに「何の機能」を作っているのかいフォーカスして作ると良いです。
メモリや再利用性なんかは優秀な先輩エンジニアがレビューでアドバイスしてくれるでしょう。