すべてのプログラムは、関数の組み合わせで出来上がっています。
プログラミングにおいて、関数は欠かせない存在です。関数の意味を分かったつもりになっているのは今後の理解力に大きな悪影響を及ぼすため、ここで丁寧に理解しておきましょう。
関数とは何か?
関数とは、渡された値をもとに、あらかじめ定められた処理を実行し、その処理結果を返す命令のことです。
※命令という言葉に違和感があるかもしれませんが、「処理」「モノ」「プログラム」などでも意味は通じます。
ここには、3つの役割が説明されています。
- 渡された値をもとに
「渡された値」は、「引数(ひきすう)」「インプット」と同じ意味です。 - あらかじめ定められた処理を実行し
この処理を行うことが、関数の主な役割です。 - その処理結果を返す
「処理結果」は、「戻り値」「アウトプット」と同じ意味です。
つまり、関数とは、「何かしらの値を渡せば、期待した結果を返してくれる処理」ということです。
たとえば、2つの数字の足し算をする関数を作る場合
- 渡す値は、2つの数字
- 定められた処理は、渡された2つの数字を足すこと
- 処理結果は、足した結果
ということになります。図で表わすと、以下のイメージです。
これらの関数がたくさん組み合わさって、1つのシステムが出来上がっています。
この関数を使う(呼び出す)処理もまた別の関数としてプログラム内に記述されていますし、またそれを呼び出す関数も存在しています。
たくさんの関数が複雑に関連しあって、1つのシステムとなっています。
ここまで話を聞いて、関数とは何かは理解できたと思います。
しかし、どのように使えば良いのかはまだイメージがついていないかもしれません。そのため、以下で紹介するような質問を今まで何度も受けてきました。
代表的な質問3つにお答えしたいと思います。
よく出る質問① 関数を分けるのはなぜか?
たとえば、ECサイトの購入履歴情報を画面に表示しようとしている場合。
画面に検索期間(2023/01/01~2023/03/31)を入力すると、その期間内で購入した商品情報を画面に表示することになります。
この場合、以下の関数を作成することになります。
この関数があれば、画面で入力された検索期間に応じて、購入履歴情報を画面に表示することができます。逆に、この関数さえあれば、購入履歴画面は作成できます。
しかし、実際のプロジェクトにあるプログラムを見ると、1つの関数で作成されていないでしょう。
画面で入力された検索期間を受け取って購入履歴情報を返す関数はありますが、その関数の中でたくさんの別の関数を呼び出しています。
購入履歴情報を表示したいだけなのに、なぜたくさんの関数に分けるのでしょうか?
この理由を考えるには、関数を作ることで得られるメリットを考える必要があります。
最初に説明したように、関数とは「何かしらの値を渡せば、期待した結果を返してくれる処理」ですが、この定義には、関数としてとても大切な特徴が含まれています。
その特徴とは、「誰がいつ呼び出しても、何かしらの値を渡せば、期待した結果を返してくれる処理」です。
最初の例で示した2つの数字を足す関数は、誰が呼び出しても2つの数字を渡しさえすれば、その値を足し算した結果を返してくれます。いつ呼び出しても渡す値が変わらなければ、結果も変わりません。
つまり、関数は一度書けば使い回しができる、ということになります。
逆に言うと、使い回しが出来るように関数を書いた方が、その後のプログラミングがより効率的に進むということになります。
この関数の特徴を考慮すると、関数を分ける理由は
「画面で入力された検索期間を受け取って購入履歴情報を返す関数」を1つの関数でまるっと作成するのは、今後のことを考えるともったいないから、ということになります。
その関数の中には他の処理でも使える記述がたくさんあるのに、1つの関数の中に書いてしまったせいで誰も使い回せない記述になってしまっているということです。
よく出る質問② 関数はどのぐらい細かく分けるのが正しいのか?
1つ目の質問で関数を分ける理由は分かりましたが、すぐに次の質問が出てきます。
「関数は、どのくらい細かく分けるものですか?」
たとえば、最初の例で示した2つの数字を足す関数の場合。3つの数字を足すのは別の関数にするのか、掛け算をしたい場合はどうするのか。
結論からお伝えしますと、明確な決まりはありません。
1つ目の質問でお伝えした通り、関数は使い回すために作成します。最初の例では足し算を関数として作成しましたが、実際のプロジェクトでは「税込金額を算出する」「商品の情報を取得する」などの業務内容に基づいて関数を分けていきます。
そのため、関数にすることも使い回したいこともシステムごとに異なることになります。明確にここを1つの関数にすると決めることはできません。
ただし、関数の細かさには1つの指標があります。
「関数の役割は、1つにする」というものです。詳しい説明は難しい話になるので避けますが、1つの関数であれもこれも出来るようにはしないということです。
これは、関数を使い回すためにある指標です。うまく使い回せるようにするには、細かい単位で関数を分けておいた方が都合が良いです。そして、小さな関数を組み合わせて大きな関数を作成します。
例えば、税込金額を算出する関数の場合。
購入した商品をもとに金額の小計を算出して、その後税率を掛けることで税込金額を算出します(軽減税率は考慮しない場合)。この場合、小計を算出する関数と小計をもとに税込金額を算出する関数は分けておくことで、他の処理で税抜金額を扱うことができるようになります。
そして、購入した商品をもとに税込金額を算出する関数では、この2つの関数を中で呼び出すことで税込金額を返します。
このように関数の中で別の関数を呼び出すことで、より大きなことをできる関数を作成していきます。そして、1つの関数の細かさや関数の数、どれを関数にするかはシステムによって異なるということになります。
よく出る質問③ 関数の分け方は、決まっていますか?
3つ目の質問は、関数の分け方についてです。
2つ目の質問でもありましたが、関数の役割は1つにするという指標があります。
この役割の決め方(何に基づいて役割を分けるか)が、関数の分け方に直結してくる考え方です。
学校のクラス委員を決める場合にたとえると分かりやすいかもしれません。
仕事の内容で分けるのであれば、学級委員や図書委員、保健委員などの委員があります。肩書で分けるのであれば、委員長、副委員長、書記などの肩書があります。そして、これらが組み合わさることで、クラス委員が出来上がります。
関数の分け方についても同じように、何に基づいて役割を分けるかの考え方がいくつかあります。
その中でも代表的なものは、以下の3つです。
- 技術で分ける
プログラミング言語が異なれば、別の関数になります。同じ処理でも違うデータベース(SqlServerとMySQLなど)にアクセスする場合は、別の関数になります。
技術の違いは、関数を分ける基準に直結します。 - 想定する関数の利用者で分ける
関数は誰でも使って良いと言いましたが、その中にも一定のルールがあります。詳しい説明は避けますが、実際にはとある関数を呼び出しても良い関数と、呼び出してはいけない関数が存在します。 - 業務内容で分ける
注文情報を管理する関数と、在庫情報を管理する関数では、似たような処理であっても関数を分ける場合があります。これは、似た業務だからと同じ関数を呼び出していた場合、どちらかの業務が変わった際に修正が大変になるからです。
この3つの視点から、1つでも違うものは別の関数にしていきます。そうすることで、役割が1つの小さな関数を作っていくことができます。
まとめ
関数について、まとめると以下のようになります。
このポイントを覚えておきましょう。
そして、自分でプログラムを作成する際には、この考え方に沿って積極的に関数に分割していきましょう。